题目大意:求一棵树被划分成两部分之后,这两部分权值和的差的绝对值的最小值
水题无误了,因为long long 没处理好WA了几次,略坑爹
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define maxn 100005
using namespace std;
typedef long long LL;
template <typename T>
T oabs(T a){return a<0?-a:a;}
template<typename T>
T omin(T a,T b){return a<b?a:b;}
LL tot,ans;
int ka;
int p[maxn];
LL num[maxn];
vector<int> g[maxn];
int n,m;
bool init()
{
int x,y;
scanf("%d%d",&n,&m);
if(n+m==0)return false;
tot=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&num[i]);
tot+=num[i];
g[i].clear();
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
ans=tot+1;
return true;
}
void build(int u)
{
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v==p[u])continue;
p[v]=u;
build(v);
}
}
void dfs(int u)
{
LL temp;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v==p[u])continue;
dfs(v);
num[u]+=num[v];
}
temp=oabs(tot-num[u]-num[u]);
ans=omin(ans,temp);
}
void solve()
{
memset(p,-1,sizeof(p));
build(1);
dfs(1);
printf("Case %d: ",ka++);
printf("%lld\n",ans);
}
int main()
{
ka=1;
while(init())
solve();
return 0;
}