- 独立做出了百度之星决赛的金牌题,开心~
- 动态转移的时候直接新开一个数组存储历史值,更清晰简洁,不给自己找麻烦
- 在memcpy语句中,被操纵的数组在前
点击查看代码
#include <bits/stdc++.h>
using namespace std;
vector<int>a[100005],c[100005];
int cnt[100005];
long long f[100005][105][2],g[105][2],len[100005];
int w[105];
int n,m;
void dp(int n1,int fa)
{if(a[n1].size()==1&&n1!=1){cnt[n1]=1;}f[n1][0][0]=f[n1][0][1]=0;for(int i=0;i<a[n1].size();i++){if(a[n1][i]!=fa){int k=a[n1][i];dp(k,n1);cnt[n1]+=cnt[a[n1][i]];memcpy(g,f[n1],sizeof(f[n1]));len[n1]=max(len[n1],len[a[n1][i]]+c[n1][i]);f[n1][0][1]=f[n1][0][1]+f[a[n1][i]][0][1]+2*c[n1][i];f[n1][0][0]=f[n1][0][1]-len[n1];for(int j=1;j<min(cnt[n1],m+1);j++){f[n1][j][0]=min(g[j][1]+f[k][0][0]+c[n1][i],g[j][0]+f[k][0][1]+2*c[n1][i]);f[n1][j][0]=min(f[n1][j][0],g[j-1][0]+f[k][0][0]+c[n1][i]);for(int l=1;l<=cnt[k];l++){if(j-l<0){break;}if(l<cnt[k]){f[n1][j][0]=min(f[n1][j][0],g[j-l][1]+f[k][l][0]+c[n1][i]);}f[n1][j][0]=min(f[n1][j][0],g[j-l][0]+f[k][l][1]+2*c[n1][i]);}}for(int j=1;j<=min(cnt[n1],m);j++){f[n1][j][1]=g[j][1]+f[k][0][1]+2*c[n1][i];f[n1][j][1]=min(f[n1][j][1],g[j-1][0]+f[k][0][0]+c[n1][i]);for(int l=1;l<=cnt[k];l++){if(j-l<0){break;}f[n1][j][1]=min(f[n1][j][1],g[j-l][1]+f[k][l][1]+2*c[n1][i]);if(j-l-1>=0){f[n1][j][1]=min(f[n1][j][1],g[j-l-1][0]+f[k][l][0]+c[n1][i]);}}}}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);memset(f,0x3f,sizeof(f));cin>>n>>m;for(int i=1;i<n;i++){int u,v,w;cin>>u>>v>>w;a[u].push_back(v);a[v].push_back(u);c[u].push_back(w);c[v].push_back(w);}for(int i=1;i<=m;i++){cin>>w[i];}dp(1,0);sort(w+1,w+m+1);int cur=0;long long ans=INT_MAX;for(int i=0;i<=min(m,cnt[1]);i++){ans=min(ans,f[1][i][1]+cur);cur+=w[i+1];}cout<<ans<<endl;return 0;
}