poj 3140 Contestants Division 树的遍历

来源:互联网 发布:电话营销软件 编辑:程序博客网 时间:2024/05/07 11:07

题意:

给一棵树,每个节点有一个值v,现在要去掉一条边,使分成的两棵树的v的和的差值最小。

分析:

水题,注意数据范围。

代码:

//poj 3140//sep9#include <iostream>using namespace std;const int maxN=200024;int n,m,e;__int64 sum,ans;struct Edge{int v,next;}edge[maxN]; __int64 v[maxN];int head[maxN];__int64 dfs(int p,int u){__int64 tmp=v[u];for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(v!=p){__int64 t=dfs(u,v);ans=min(ans,max(t,sum-t)-min(t,sum-t));tmp+=t;}}return tmp;}int main(){int cases=0;while(scanf("%d%d",&n,&m)==2&&n){e=0,sum=0;memset(head,-1,sizeof(head));for(int i=1;i<=n;++i){scanf("%I64d",&v[i]);sum+=v[i];}while(m--){int a,b;scanf("%d%d",&a,&b);edge[e].v=b;edge[e].next=head[a];head[a]=e++;edge[e].v=a;edge[e].next=head[b];head[b]=e++;}ans=sum;dfs(-1,1);printf("Case %d: %I64d\n",++cases,ans);}return 0;} 


0 0