题意很扯,就是给一棵树,每个结点有个值,然后把图劈成两半,差值最小,反正各种扯。
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 }