Poj--3140(Dfs,枚举树边)
2014-12-09 21:35:31
思路:Dfs一遍,找树大小,然后在过程中找答案即可。
注意:最大值以后可以以-1设为第一个元素前的标记,以防止题目卡INF!
1 /************************************************************************* 2 > File Name: 3140.cpp 3 > Author: Natureal 4 > Mail: 564374850@qq.com 5 > Created Time: Tue 09 Dec 2014 12:30:04 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int maxn = 100010; 26 const int Maxn = 1000010; 27 28 int N,M; 29 ll num[maxn],ans,sum; 30 int first[maxn],next[Maxn],ver[Maxn],ecnt; 31 32 void Init(){ 33 memset(first,-1,sizeof(first)); 34 ecnt = 0; 35 sum = 0; 36 } 37 38 void Add_edge(int u,int v){ 39 next[++ecnt] = first[u]; 40 ver[ecnt] = v; 41 first[u] = ecnt; 42 } 43 44 ll Solve(int p,int fa){ 45 ll sz = num[p]; 46 for(int i = first[p]; i != -1; i = next[i]){ 47 int v = ver[i]; 48 if(v == fa) 49 continue; 50 ll tmp = Solve(v,p); 51 ll res = sum - tmp - tmp; 52 if(res < 0) res = -res; 53 if(ans == -1) ans = res; 54 else ans = min(ans,res); 55 sz += tmp; 56 } 57 return sz; 58 } 59 60 int main(){ 61 int a,b,Case = 0; 62 while(scanf("%d%d",&N,&M) != EOF){ 63 if(N == 0 && M == 0) 64 break; 65 Init(); 66 for(int i = 1; i <= N; ++i){ 67 scanf("%I64d",&num[i]); 68 sum += num[i]; 69 } 70 for(int i = 1; i <= M; ++i){ 71 scanf("%d%d",&a,&b); 72 Add_edge(a,b); 73 Add_edge(b,a); 74 } 75 ans = -1; 76 Solve(1,0); 77 printf("Case %d: %I64d\n",++Case,ans); 78 } 79 return 0; 80 }