m的大小是哄人的,其实m恒等于n-1,然后就是很普通的树形dp了,注意用long long

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll INF = 1e12;
const int maxn = 1e5 + 10;

int n, m;
ll dp[maxn];
int tot, head[maxn];
struct Edge {
int to, next;
}edge[maxn<<1];
void init() {
tot = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v) {
++tot;
edge[tot].to = v, edge[tot].next = head[u];
head[u] = tot;
}

void dfs(int u, int p) {
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].to;
if (v == p) continue;
dfs(v, u);
dp[u] += dp[v];
}
}

ll iabs(ll x) {
return x >= 0 ? x : -x;
}

int main() {
int flag = 0;
while (~scanf("%d %d", &n, &m) && (n + m)) {
if (m != n - 1) {
for (int i = 1; ;i++);
}
init();
int u, v;
ll sum = 0;
for (int i = 1; i <= n; i++) {
scanf("%lld", &dp[i]);
sum += dp[i];
}
for (int i = 1; i <= m; i++) {
scanf("%d %d", &u, &v);
addedge(u, v); addedge(v, u);
}
dfs(1, -1);
// for (int i = 1; i <= n; i++) cout << dp[i] << " ";
// cout << endl;
ll ans = INF;
for (int i = 1; i <= n; i++) {
ll a = dp[i], b = sum - dp[i];
ans = min(ans, iabs(a - b));
}
printf("Case %d: %lld\n", ++flag, ans);
}
return 0;
}