poj 3140(树形dp)

题目链接:http://poj.org/problem?id=3140

思路:简单树形dp题,dp[u]表示以u为根的子树的人数和。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<climits>
 7 #include<algorithm>
 8 #include<stack>
 9 #include<map>
10 #include<set>
11 #include<vector>
12 #include<queue>
13 #include<list>
14 using namespace std;
15 #define MAXN 111111
16 #define inf 1<<30
17 #define INF 1LL<<60
18 typedef long long ll;
19 typedef pair<int,int>PP;
20 template<class T> inline T Get_MIN(const T &a,const T &b){ return a < b ? a : b; }
21 template<class T> inline T Get_MAX(const T &a,const T &b){ return a > b ? a : b; }
22 template<class T> inline T ABS(const T &a){ return a < 0 ? -a : a; }
23 
24 struct Edge{
25     int v,next;
26 }edge[MAXN<<4];
27 
28 int n,m,NE;
29 int head[MAXN];
30 
31 void Insert(int u,int v)
32 {
33     edge[NE].v=v;
34     edge[NE].next=head[u];
35     head[u]=NE++;
36 }
37 
38 ll dp[MAXN],sum,MIN;
39 void dfs(int u,int father)
40 {
41     for(int i=head[u];i!=-1;i=edge[i].next){
42         int v=edge[i].v;
43         if(v==father)continue;
44         dfs(v,u);
45         dp[u]+=dp[v];
46     }
47     MIN=Get_MIN(MIN,ABS((dp[u]-(sum-dp[u]))));
48    // cout<<u<<"**"<<dp[u]<<"****"<<abs(sum-dp[u])<<"**"<<MIN<<endl;
49 }
50 
51 
52 int main()
53 {
54     int u,v,t=1;
55     while(~scanf("%d%d",&n,&m)&&(n||m)){
56         NE=0;
57         memset(head,-1,sizeof(head));
58         sum=0;
59         for(int i=1;i<=n;i++)scanf("%lld",&dp[i]),sum+=dp[i];
60         while(m--){
61             scanf("%d%d",&u,&v);
62             Insert(u,v);
63             Insert(v,u);
64         }
65         MIN=INF;
66         dfs(1,-1);
67         printf("Case %d: %lld
",t++,MIN);
68     }
69     return 0;
70 }
View Code
原文地址:https://www.cnblogs.com/wally/p/3349620.html