POJ 3140(简单树形DP)
来源:互联网 发布:矩阵列归一化 编辑:程序博客网 时间:2024/05/23 15:47
/***************************************************** author:crazy_石头* Pro:POJ 3140* algorithm:树形DP+枚举* Time:313ms* Judge Status:Accepted* /*Description:* 给定一颗点上带权树,删除一条边,问剩下的两颗子树权值差的最小值;* 思路:dfs找子树权值,设一颗的权值为tmp,那么另一颗子树权值为tot-tmp;* 所以枚举所有子树,找出绝对值最小值即可;* 那么答案为:ans=min(tmp,abs(tot-tmp-tmp));*******************************************************/#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <vector>#include <algorithm>using namespace std;#define rep(i,h,n) for(int i=(h);i<=(n);i++)#define ms(a,b) memset((a),(b),sizeof(a))#define eps 1e-6#define INF 1<<29#define LL long longusing namespace std;const int maxn=1000000+10;struct E{ int to,next;}e[maxn<<1];int head[maxn],cnt;LL num[maxn];LL ans,tot;inline void addedge(int u,int v){ e[cnt].to=v; e[cnt].next=head[u]; head[u]=cnt++;}inline LL ABS(LL u){ return u<0?-u:u;}inline void dfs(int u,int father){ for(int i=head[u];~i;i=e[i].next) { int v=e[i].to; if(v==father)continue; dfs(v,u); num[u]+=num[v]; } ans=min(ans,ABS((tot-num[u])-num[u]));}int main(){ int n,m,t=1; while(~scanf("%d%d",&n,&m),n,m) { tot=0; ms(head,-1); cnt=0; rep(i,1,n) { scanf("%lld",&num[i]); tot+=num[i]; } while(m--) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } ans=tot; dfs(1,-1); printf("Case %d: %lld\n",t++,ans); } return 0;}