Contestants Division POJ - 3140

原题链接

考察:树形dp(?)

思路:

        f[i]表示i往下(包括i)的点权值和.对比学生总和sum-f[i]与f[i]的大小即可.

这题貌似和m没多大关系.m一定=n-1.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 typedef long long ll;
 6 const int N = 100010,M = 1000010;
 7 ll f[N],ans,sum;
 8 int s[N],h[N],idx,n,m,kcase;
 9 struct Road{
10     int to,ne;
11 }road[M];
12 void inits()
13 {
14     idx = 0; memset(h,-1,sizeof h); sum = 0;
15     memset(f,0,sizeof f);
16 }
17 void add(int a,int b)
18 {
19     road[idx].to = b; road[idx].ne = h[a],h[a] = idx++;
20 }
21 ll abss(ll a)
22 {
23     if(a<0) return -a;
24     else return a;
25 }
26 ll dfs(int u,int fa)
27 {
28     f[u] = s[u];
29     for(int i=h[u];i!=-1;i=road[i].ne)
30     {
31         int v = road[i].to;
32         if(v==fa) continue;
33         f[u] += dfs(v,u);
34     }
35     ans = min(ans,abss(sum-f[u]-f[u]));
36     return f[u];
37 }
38 int main() 
39 {
40     while(scanf("%d%d",&n,&m)!=EOF&&(n+m))
41     {
42         inits();
43         for(int i=1;i<=n;i++) scanf("%d",&s[i]),sum=sum+s[i];
44         ans = sum;
45         for(int i=1;i<=m;i++)
46         {
47             int x,y; scanf("%d%d",&x,&y);
48             add(x,y); add(y,x);
49         }
50         dfs(1,-1);
51         printf("Case %d: %lld\n",++kcase,ans);
52     }
53     return 0;
54 }

 

说实话这题写的我好没把握啊233,抱着感觉会T的想法交了.

posted @ 2021-02-16 22:19  acmloser  阅读(57)  评论(0编辑  收藏  举报