解题思路:题目大意就是一棵树去掉一条边,得到树两边的差值最小。典型的dfs树形Dp
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100009
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
struct node
{
int v,next;
}s[N];
int a[N],head[N],cnt;
ll p[N],ans,sum;
void add_edge(int b,int c)
{
s[cnt].v=c;
s[cnt].next=head[b];
head[b]=cnt++;
s[cnt].v=b;
s[cnt].next=head[c];
head[c]=cnt++;
}
void dfs(int u,int pre)
{
p[u]=a[u];
for(int i=head[u];i!=-1;i=s[i].next)
{
int v=s[i].v;
if(v==pre) continue;
dfs(v,u);
p[u]+=p[v];
}
ans=min(ans,abs(p[u]-(sum-p[u])));
}
int main()
{
//freopen("t.txt","r",stdin);
int n,m,b,c,t=0;
while(1)
{
t++;
scanf("%d%d",&n,&m);
if(n+m==0) break;
printf("Case %d: ",t);
sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
memset(head,-1,sizeof(head));
cnt=0;
while(m--)
{
scanf("%d%d",&b,&c);
add_edge(b,c);
}
ans=inf;
dfs(1,-1);
printf("%lld\n",ans);
}
return 0;
}