POJ 3140 Contestants Division——树形dp

来源:互联网 发布:javascript知识点总结 编辑:程序博客网 时间:2024/05/16 09:10

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;}


原创粉丝点击