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