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;}