标签:dfs ret 树形dp ext locate scribe end cat integer
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1346 Accepted Submission(s): 397
//先dfs求出以1为根节点使每个点后代到这个点集合的花费sum以及这个点及其后代共有几个人cnt //然后枚举每个点i作为集合点(根节点)时他的花费就是sum[i]+他的父节点减去从i来的人的花费+ //父节点总人数减去从i来的人数*边权值。并且更新最小花费和sum[i],cnt[i]. #include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int maxn=100009; int n,val[maxn],head[maxn],cnt[maxn],tol; ll sum[maxn],ans; struct node{ int to,w,next; }nodes[maxn*2]; void Add(int x,int y,int z){ nodes[tol].to=y; nodes[tol].w=z; nodes[tol].next=head[x]; head[x]=tol++; } void dfs(int x,int fa){ cnt[x]=val[x];sum[x]=0; for(int i=head[x];i!=-1;i=nodes[i].next){ int y=nodes[i].to; if(y==fa) continue; dfs(y,x); cnt[x]+=cnt[y]; sum[x]+=(sum[y]+1LL*cnt[y]*nodes[i].w); } } void dfs1(int x,int fa){ for(int i=head[x];i!=-1;i=nodes[i].next){ int y=nodes[i].to; if(y==fa) continue; sum[y]=sum[y]+sum[x]-sum[y]-1LL*cnt[y]*nodes[i].w+1LL*(cnt[x]-cnt[y])*nodes[i].w; cnt[y]+=(cnt[x]-cnt[y]); //cout<<y<<" "<<sum[y]<<endl; //ans=min(ans,sum[y]+sum[x]-sum[y]-1LL*cnt[y]*nodes[i].w+1LL*(cnt[x]-cnt[y])*nodes[i].w); ans=min(ans,sum[y]); dfs1(y,x); } } int main() { while(scanf("%d",&n)==1){ memset(val,0,sizeof(val)); memset(head,-1,sizeof(head)); tol=0; for(int i=1;i<=n;i++) scanf("%d",&val[i]); for(int i=1;i<n;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); Add(x,y,z); Add(y,x,z); } dfs(1,0); ans=sum[1]; dfs1(1,0); printf("%I64d\n",ans); } return 0; }
标签:dfs ret 树形dp ext locate scribe end cat integer
原文地址:http://www.cnblogs.com/--ZHIYUAN/p/6850287.html