题目链接: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 }