省选测试3

A 天空碎片 (Unaccepted)

题目大意 :

  • 咕咕咕

Code

Show Code

B 未来拼图 (Unaccepted)

题目大意 :

  • 咕咕咕

Code

Show Code

C 完美理论

题目大意 : 给两颗点集相同的树,找到一个权值和最大的子集满足在两颗树上都是联通的。

  • 枚举一个根并强制选择根,那现在如果选一个点,就需要选他多有的祖先,这样就转换成了最大权闭合子图的形式

Code

Show Code
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>

const int N = 105;

int read(int x = 0, int f = 1, char c = getchar()) {
    for (; c < '0' || c > '9'; c = getchar())
        if (c == '-') f = -1;
    for (; c >='0' && c <='9'; c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

struct Edge {
    int n, t, d;
}e[N*4];
int h[N], edc;

void Add(int x, int y, int z = 1e5) {
    e[++edc] = (Edge) {h[x], y, z}; h[x] = edc;
    e[++edc] = (Edge) {h[y], x, 0}; h[y] = edc;
}

int n, a[N], sum, s, t, mx, dep[N], q[N], l, r, tmp[N];
std::vector<int> t1[N], t2[N];

void Dfs(int x, int fa, std::vector<int> *t) {
    if (fa) Add(x, fa);
    for (int i = 0, y; i < t[x].size(); ++i)
        if ((y = t[x][i]) != fa) Dfs(y, x, t);
}

bool Bfs() {
    memset(dep + 1, 0, t * 4);
    memcpy(h + 1, tmp + 1, t * 4);
    dep[s] = 1; q[l=r=1] = s;
    while (l <= r) {
        int x = q[l++];
        for (int i = h[x], y; i; i = e[i].n) {
            if (!e[i].d || dep[y=e[i].t]) continue;
            dep[y] = dep[x] + 1; q[++r] = y;
            if (y == t) return 1;
        }
    }
    return 0;
}

int Dinic(int x, int lim) {
    if (x == t) return lim;
    int sum = 0;
    for (int i = h[x]; i && lim; i = e[i].n) {
        int y = e[i].t; h[x] = i;
        if (!e[i].d || dep[y] != dep[x] + 1) continue;
        int f = Dinic(y, std::min(lim, e[i].d));
        sum += f; lim -= f;
        e[i].d -= f; e[i^1].d += f;
    }
    if (!sum) dep[x] = 0;
    return sum;
}

int main() {
    for (int T = read(); T; --T) {
        n = read(); sum = mx = 0; 
        s = n + 1; t = s + 1;
        for (int i = 1; i <= n; ++i) {
            a[i] = read(), t1[i].clear(), t2[i].clear();
            if (a[i] > 0) sum += a[i];
        }
        for (int i = 1; i < n; ++i) {
            int x = read(), y = read();
            t1[x].push_back(y); t1[y].push_back(x);
        }
        for (int i = 1; i < n; ++i) {
            int x = read(), y = read();
            t2[x].push_back(y); t2[y].push_back(x);
        }
        for (int i = 1; i <= n; ++i) {
            int ans = sum; edc = 1;
            memset(h + 1, 0, t * 4);
            Dfs(i, 0, t1); Dfs(i, 0, t2); 
            for (int j = 1; j <= n; ++j)
                a[j] > 0 ? Add(s, j, a[j]) : Add(j, t, -a[j]);
            memcpy(tmp + 1, h + 1, t * 4);
            while (Bfs()) ans -= Dinic(s, 1e5);
            mx = std::max(mx, ans);
        }
        printf("%d
", mx);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shawk/p/14369588.html