1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| #include<bits/stdc++.h> using namespace std; #define ll long long const int INF = 0x3f3f3f3f; const int N = 510; const ll mod = 998244353; int n; vector<int>G1[N], G2[N]; int dp[N][N], r1, r2; typedef pair<int, int>pii; struct E { int from, to, cp, v; int rev; E() {} E(int f, int t, int cp, int v, int rev) :from(f), to(t), cp(cp), v(v), rev(rev) {} }; struct MCMF { int n, m, s, t; vector<E> edges; vector<int> G[N << 1]; bool inq[N << 1]; int d[N << 1]; int p[N << 1]; int a[N << 1]; 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.push_back(E(from, to, cap, cost, 0)); edges.push_back(E(to, from, 0, -cost, 1)); G[from].push_back(m++); G[to].push_back(m++); }
bool BellmanFord(int &flow, int &cost) { for (int i = 0; i < n; i++) d[i] = INF; memset(inq, 0, sizeof inq); d[s] = 0, a[s] = INF, inq[s] = true; queue<int> Q; 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.cp && d[e.to] > d[u] + e.v) { d[e.to] = d[u] + e.v; p[e.to] = idx; a[e.to] = min(a[u], e.cp); if (!inq[e.to]) { Q.push(e.to); inq[e.to] = true; } } } } if (d[t] == INF) return false; flow += a[t]; cost += a[t] * d[t]; int u = t; while (u != s) { edges[p[u]].cp -= a[t]; edges[p[u] ^ 1].cp += a[t]; u = edges[p[u]].from; } return true; }
pii go() { int flow = 0, cost = 0; while (BellmanFord(flow, cost)); return pii(flow, cost); } } MM;
int dfs(int u1, int u2) { if (~dp[u1][u2])return dp[u1][u2]; if (G1[u1].size() != G2[u2].size())return dp[u1][u2] = 999; for (int v1 : G1[u1]) { for (int v2 : G2[u2]) { dfs(v1, v2); } } int S = 0, T = 2 * n + 1; MM.init(2 * n + 2, S, T); for (int v : G1[u1])MM.addedge(S, v, 1, 0); for (int v : G2[u2])MM.addedge(v + n, T, 1, 0); for (int v1 : G1[u1]) { for (int v2 : G2[u2]) { MM.addedge(v1, v2 + n, 1, dp[v1][v2]); } } int res = MM.go().second; if (u1 != u2)res++; return dp[u1][u2] = min(res, 999); } int main() { scanf("%d", &n); memset(dp, -1, sizeof(dp)); for (int i = 1; i <= n; i++) { int f; scanf("%d", &f); if (f)G1[f].push_back(i); else r1 = i; } for (int i = 1; i <= n; i++) { int f; scanf("%d", &f); if (f)G2[f].push_back(i); else r2 = i; } printf("%d\n", dfs(r1, r2)); return 0; }
|