1 条题解
-
0

#include <bits/stdc++.h> #define ctz __builtin_ctz using std::cin; using std::cout; const int N = 1023, M = N * 2; typedef std::bitset <N> bitset; int n, q, E; int to[M], first[N], next[M]; int f[N]; bitset F[N], G[N]; inline void up(int &x, const int y) {x < y ? x = y : 0;} namespace matching { int n, ALL; int G[15], f[1054], replaceable; inline void reset(int n_) {n = n_, memset(G, 0, n << 2);} inline void link(int x, int y) {G[x] |= 1 << y, G[y] |= 1 << x;} int main() { int i, v, S; ALL = ~(-1 << n); for (i = 1; i <= ALL; ++i) for (f[i] = f[i & (i - 1)], v = ctz(i), S = G[v] & i; S; S &= S - 1) up(f[i], f[i & (i - 1) & ~(S & -S)] + 1); for (replaceable = i = 0; i < n; ++i) replaceable |= (f[ALL & ~(1 << i)] == f[ALL]) << i; return f[ALL]; } } inline void addedge(int u, int v) { to[++E] = v, next[E] = first[u], first[u] = E; to[++E] = u, next[E] = first[v], first[v] = E; } void dfs(int x, int px = 0) { int i, j, y, u, v, w, c[15], d = 0, c1[15], d1 = 0; bitset t; f[x] = 0; for (i = first[x]; i; i = next[i]) if ((y = to[i]) != px) dfs(y, x), c[d++] = y, f[x] += f[y]; assert(d < 11); for (i = 0; i < d; ++i) if (y = c[i], (G[x] & F[y]).any()) ++f[x]; else c1[d1++] = y; matching::reset(d1); for (i = 0; i + 1 < d1; ++i) { u = c1[i], t.reset(); for (w = F[u]._Find_first(); w != N; w = F[u]._Find_next(w)) t |= G[w]; for (j = i + 1; j < d1; ++j) if (v = c1[j], (t & F[v]).any()) matching::link(i, j); } f[x] += matching::main(), F[x].set(x); for (w = matching::replaceable; w; w &= w - 1) F[x] |= F[c1[ctz(w)]]; } void work() { int i, u, v; E = 0; cin >> n, memset(first, 0, (n + 1) << 2); for (i = 1; i < n; ++i) cin >> u >> v, addedge(u, v); for (i = 1; i <= n; ++i) F[i].reset(), G[i].reset(); cin >> q; for (i = 0; i < q; ++i) cin >> u >> v, G[u].set(v), G[v].set(u); dfs(1), cout << f[1] << '\n'; } int main() { int T; std::ios::sync_with_stdio(false), cin.tie(NULL); for (cin >> T; T; --T) work(); return 0; }
- 1
信息
- ID
- 5707
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者