POJ 3140 Contestants Division

题目链接

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

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

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <cmath>
 5 #include <algorithm>
 6 using namespace std;
 7 #define LL __int64
 8 struct node
 9 {
10     int u,v,next;
11 }edge[2000001];
12 LL p[100001];
13 LL dp[100001];
14 int first[100001];
15 int o[100001];
16 int t;
17 LL ans,sum;
18 void CL()
19 {
20     t = 1;
21     memset(first,-1,sizeof(first));
22     memset(dp,0,sizeof(dp));
23     memset(o,0,sizeof(o));
24 }
25 void add(int u,int v)
26 {
27     edge[t].u = u;
28     edge[t].v = v;
29     edge[t].next = first[u];
30     first[u] = t ++;
31 }
32 void dfs(int x)
33 {
34     int i;
35     LL minz,res;
36     if(o[x]) return ;
37     o[x] = 1;
38     res = p[x];
39     for(i = first[x];i != -1;i = edge[i].next)
40     {
41         dfs(edge[i].v);
42         res += dp[edge[i].v];
43     }
44     dp[x] = res;
45     minz = (sum - res) - res;
46     if(minz < 0) minz = -minz;
47     if(ans > minz)
48     ans = minz;
49 }
50 int main()
51 {
52     int n,m,i,u,v,cas = 1;
53     while(scanf("%d%d",&n,&m)!=EOF)
54     {
55         if(!n && !m) break;
56         sum = 0;
57         CL();
58         for(i = 1;i <= n;i ++)
59         {
60             scanf("%I64d",&p[i]);
61             sum += p[i];
62         }
63         ans = sum;
64         for(i = 0;i < m;i ++)
65         {
66             scanf("%d%d",&u,&v);
67             add(u,v);
68             add(v,u);
69         }
70         for(i = 1;i <= n;i ++)
71         {
72             if(!o[i])
73             {
74                 dfs(i);
75             }
76         }
77         printf("Case %d: %I64d
",cas++,ans);
78     }
79     return 0;
80 }
原文地址:https://www.cnblogs.com/naix-x/p/3204831.html