poj 3140 简单dfs

来源:互联网 发布:lt1953wa淘宝 编辑:程序博客网 时间:2024/05/18 18:18

给定一棵树,每个节点有一个权值。任意去掉一条边会形成两颗子树,每颗子树有一个权值和,求二者相差的最小值。

dfs的时候求出当前节点和其子树的节点的总权值w,并和sum-w相减,和ans比较即可

View Code
 1 #include<stdio.h>
2 #include<string.h>
3 #include<vector>
4 using namespace std;
5 vector<int> mm[100010];
6 int W[100010];
7 bool vis[100010];
8 __int64 ans,sum;
9 __int64 ABS(__int64 a)
10 {
11 if(a<0) return -a;
12 return a;
13 }
14 void Min(__int64 &a,__int64 b)
15 {
16 if(a>b) a=b;
17 }
18 __int64 dfs(int x)
19 {
20 int i,j;
21 vis[x]=true;
22 __int64 ret=W[x];
23 for(i=0;i<mm[x].size();i++)
24 {
25 if(!vis[mm[x][i]])
26 {
27 ret+=dfs(mm[x][i]);
28 }
29 }
30 Min(ans,ABS(sum-ret-ret));
31 return ret;
32 }
33 int main()
34 {
35 int n,m,i,j,a,b;
36 int cases=1;
37 while(scanf("%d%d",&n,&m)!=EOF)
38 {
39 if(n==0&&m==0) break;
40 for(i=0;i<=n;i++)
41 {
42 mm[i].clear();
43 vis[i]=false;
44 }
45 sum=0;
46 for(i=1;i<=n;i++)
47 {
48 scanf("%d",&W[i]);
49 sum+=W[i];
50 }
51 for(i=0;i<m;i++)
52 {
53 scanf("%d%d",&a,&b);
54 mm[a].push_back(b);
55 mm[b].push_back(a);
56 }ans=((__int64)1<<60);
57 dfs(1);
58 printf("Case %d: %I64d\n",cases++,ans);
59 }
60 return 0;
61 }



原创粉丝点击