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\n",t++,MIN);

68     }

69     return 0;

70 }
View Code

 

你可能感兴趣的:(poj)