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\n",cas++,ans);

78     }

79     return 0;

80 }

 

你可能感兴趣的:(visio)