8.10 2020牛客暑期多校训练营(第十场)题解及补题
include <bits/stdc++.h>
define IO ios::sync_with_stdio(0), cin.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1010;
const int INF=0x3f3f3f3f;
typedef pair<int, int> P;
define REP(i, a, n) for (int i = a; i < (n); ++i)
define PER(i, a, n) for (int i = (n)-1; i >= a; --i)
const ll mod = 1e9 + 7;
struct node {
int to, next;
} e1[maxn], e2[maxn];
int cnt1, head1[maxn], cntt1[maxn], cnt2, head2[maxn], cntt2[maxn];
ull hash1[maxn], hash2[maxn];
void add1(int u, int v) {
e1[cnt1].to = v;
e1[cnt1].next = head1[u];
head1[u] = cnt1++;
cntt1[u]++;
}
void add2(int u, int v) {
e2[cnt2].to = v;
e2[cnt2].next = head2[u];
head2[u] = cnt2++;
cntt2[u]++;
}
ull gethash1(int x) {
vector
for (int i = head1[x]; ~i; i = e1[i].next) v.push_back(gethash1(e1[i].to));
sort(v.begin(), v.end());
ull h = 28;
for (ull i : v) h = h * (ull)13131 + i;
hash1[x] = h;
return h;
}
ull gethash2(int x) {
vector
for (int i = head2[x]; ~i; i = e2[i].next) v.push_back(gethash2(e2[i].to));
sort(v.begin(), v.end());
ull h = 28;
for (ull i : v) h = h * (ull)13131 + i;
hash2[x] = h;
return h;
}
struct MCMF {
struct E {
int from, to, cap, v;
E() {}
E(int f, int t, int cap, int v) : from(f), to(t), cap(cap), v(v) {}
};
int n, m, s, t;
vector
vector
bool inq[maxn];
int dis[maxn], pre[maxn], a[maxn];
void init(int _n, int _s, int _t) {
n = _n;
s = _s;
t = _t;
for (int i = 0; i <= n; i++) G[i].clear();
edges.clear();
m = 0;
}
void addedge(int from, int to, int cap, int cost) {
edges.emplace_back(from, to, cap, cost);
edges.emplace_back(to, from, 0, -cost);
G[from].emplace_back(m++);
G[to].emplace_back(m++);
}
bool spfa() {
for (int i = 0; i <= n; i++) {
dis[i] = INF;
pre[i] = -1;
inq[i] = false;
}
dis[s] = 0, a[s] = INF, inq[s] = true;
queue
Q.push(s);
while (!Q.empty()) {
int u = Q.front();
Q.pop();
inq[u] = false;
for (int& idx : G[u]) {
E& e = edges[idx];
if (e.cap && dis[e.to] > dis[u] + e.v) {
dis[e.to] = dis[u] + e.v;
pre[e.to] = idx;
a[e.to] = min(a[u], e.cap);
if (!inq[e.to]) {
inq[e.to] = true;
Q.push(e.to);
}
}
}
}
return pre[t] != -1;
}
int solve() {
int flow = 0, cost = 0;
while (spfa()) {
flow += a[t];
cost += a[t] * dis[t];
int u = t;
while (u != s) {
edges[pre[u]].cap -= a[t];
edges[pre[u] ^ 1].cap += a[t];
u = edges[pre[u]].from;
}
}
return cost;
}
};
int match(int p1, int p2) {
if (head1[p1] == -1 && head2[p2] == -1) return (p1 == p2 ? -1 : 0);
int sum = cntt1[p1] + cntt2[p2];
MCMF f;
f.init(sum + 2, sum + 1, sum + 2);
for (int i = head1[p1], ii = 0; ~i; i = e1[i].next, ii++) {
f.addedge(f.s, ii, 1, 0);
for (int j = head2[p2], jj = 0; ~j; j = e2[j].next, jj++) {
if (hash1[e1[i].to] == hash2[e2[j].to])
f.addedge(
ii, jj + cntt1[p1], 1,
match(e1[i].to,
e2[j].to));
}
}
for (int j = head2[p2], jj = 0; ~j; j = e2[j].next, jj++)
f.addedge(jj + cntt1[p1], f.t, 1,
0);
return f.solve() + (p1 == p2 ? -1 : 0);
}
int main() {
IO;
int n;
cin >> n;
int p;
memset(head1, -1, sizeof(head1));
memset(head2, -1, sizeof(head2));
int root1, root2;
REP(i, 1, n + 1) {
cin >> p;
if (!p) {
root1 = i;
} else {
add1(p, i);
}
}
REP(i, 1, n + 1) {
cin >> p;
if (!p) {
root2 = i;
} else {
add2(p, i);
}
}
gethash1(root1);
gethash2(root2);
cout << n + match(root1, root2) << endl;
return 0;
}

浙公网安备 33010602011771号