poj3140,树

来源:互联网 发布:淘宝店铺联盟分享店铺 编辑:程序博客网 时间:2024/04/30 03:47

给一个树形结构,每个点又权值,要求把它分成两部分使得两部分权值总和的差距最小。

这里要注意的是,abs好像不能处理64位整形,所以取绝对值函数要手写。

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#define INF 2000000000__int64 dp[1000005],first[1000005],next[2000005],num[1000005],sum,min,n;struct edge{    __int64 u;    __int64 v;}en[2000005];void add(__int64 a,__int64 b,__int64 p){    en[p].u=a;    en[p].v=b;    next[p]=first[a];    first[a]=p;}void getdp(__int64 s,__int64 f){    __int64 i;    for(i=first[s];i!=-1;i=next[i])    {        if(en[i].v!=f)        {            getdp(en[i].v,s);            dp[s]+=dp[en[i].v];        }    }    dp[s]+=num[s];}__int64 ju(__int64 a){    if(a<0)        return -a;    else        return a;}void getmin(){    __int64 i,j,a;    for(i=2,min=ju(sum-dp[1]-dp[1]);i<=n;i++)    {        a=ju(sum-dp[i]-dp[i]);        if(a<min)            min=a;    }}int main(){    __int64 m,i,j,k,l,a,b,idx,t;    t=0;    while(scanf("%I64d%I64d",&n,&m)!=EOF)    {        if(n==0&&m==0)            break;        t++;        for(i=1,sum=0;i<=n;i++)        {            scanf("%I64d",&num[i]);            sum+=num[i];        }        idx=0;        memset(first,-1,sizeof(first));        memset(next,-1,sizeof(next));        memset(dp,0,sizeof(dp));        for(i=1;i<=m;i++)        {            scanf("%I64d%I64d",&a,&b);            idx++;            add(a,b,idx);            idx++;            add(b,a,idx);        }        getdp(1,-1);        getmin();        printf("Case %I64d: %I64d\n",t,min);    }    return 0;}


0 0
原创粉丝点击