POJ 3140 Contestants Division

时间:2023-03-09 07:30:21
POJ 3140 Contestants Division

题目链接

题意很扯,就是给一棵树,每个结点有个值,然后把图劈成两半,差值最小,反正各种扯。

2B错误,导致WA了多次,无向图,建图搞成了有向了....

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define LL __int64
struct node
{
int u,v,next;
}edge[];
LL p[];
LL dp[];
int first[];
int o[];
int t;
LL ans,sum;
void CL()
{
t = ;
memset(first,-,sizeof(first));
memset(dp,,sizeof(dp));
memset(o,,sizeof(o));
}
void add(int u,int v)
{
edge[t].u = u;
edge[t].v = v;
edge[t].next = first[u];
first[u] = t ++;
}
void dfs(int x)
{
int i;
LL minz,res;
if(o[x]) return ;
o[x] = ;
res = p[x];
for(i = first[x];i != -;i = edge[i].next)
{
dfs(edge[i].v);
res += dp[edge[i].v];
}
dp[x] = res;
minz = (sum - res) - res;
if(minz < ) minz = -minz;
if(ans > minz)
ans = minz;
}
int main()
{
int n,m,i,u,v,cas = ;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(!n && !m) break;
sum = ;
CL();
for(i = ;i <= n;i ++)
{
scanf("%I64d",&p[i]);
sum += p[i];
}
ans = sum;
for(i = ;i < m;i ++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(i = ;i <= n;i ++)
{
if(!o[i])
{
dfs(i);
}
}
printf("Case %d: %I64d\n",cas++,ans);
}
return ;
}