不知道为什么会是agc的F。
考虑
P
P
P和
Q
Q
Q形成了若干个环。对于一个非平凡的环,有两种状态,即对于环上的数
i
i
i全部有
A
i
=
i
A_i=i
Ai=i或
A
i
=
P
i
A_i=P_i
Ai=Pi(
P
i
≠
i
P_i\neq i
Pi=i)。这样可以将每个非平凡环作为一个
0
/
1
0/1
0/1变量,而距离可以理解为对于某些
P
P
P中的环和
Q
Q
Q中的环的组合,变量同时取
0
0
0或同时取
1
1
1要付出
1
1
1的代价。
这样可以直接最小割。建图的时候还要特殊考虑平凡环(
P
i
=
i
P_i=i
Pi=i或
Q
i
=
i
Q_i=i
Qi=i)的影响。
使用dinic算法时间复杂度为
O
(
N
N
)
\mathcal O(N\sqrt N)
O(NN)。
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int t,f,next;
Edge() {}
Edge(int a,int b,int c):t(a),f(b),next(c) {}
};
Edge e[2000000];
int head[200005],vs,vt,tot=-1;
inline void addEdge(int x,int y,int z) {
e[++tot]=Edge(y,z,head[x]);
head[x]=tot;
e[++tot]=Edge(x,0,head[y]);
head[y]=tot;
}
namespace Flow {
int d[200005],cur[200005];
queue <int> q;
bool bfs() {
while (!q.empty()) q.pop();
memset(d,255,sizeof(d));
d[vs]=0;cur[vs]=head[vs];
q.push(vs);
while (!q.empty()) {
int x=q.front();q.pop();
for(int i=head[x];i!=-1;i=e[i].next)
if (e[i].f&&d[e[i].t]==-1) {
int u=e[i].t;
d[u]=d[x]+1;
cur[u]=head[u];
if (u==vt) return 1;
q.push(u);
}
}
return 0;
}
int dfs(int x,int a) {
if (x==vt||!a) return a;
int ans=0;
for(int &i=cur[x];i!=-1;i=e[i].next)
if (e[i].f&&d[e[i].t]==d[x]+1) {
int u=e[i].t;
int f=dfs(u,min(a,e[i].f));
if (f) {
e[i].f-=f;
e[i^1].f+=f;
ans+=f;
a-=f;
if (!a) break;
}
}
return ans;
}
int maxflow() {
int ans=0;
while (bfs())
ans+=dfs(vs,1e9);
return ans;
}
}
int a[100005],b[100005];
int id1[100005],id2[100005];
int main() {
memset(head,255,sizeof(head));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]++;
for(int i=1;i<=n;i++) scanf("%d",&b[i]),b[i]++;
int cnt1=0,cnt2=0;
for(int i=1;i<=n;i++)
if (!id1[i]) {
int x=i;
cnt1++;
do {
id1[x]=cnt1;
x=a[x];
} while (x!=i);
}
for(int i=1;i<=n;i++)
if (!id2[i]) {
int x=i;
cnt2++;
do {
id2[x]=cnt2;
x=b[x];
} while (x!=i);
}
vs=0;vt=cnt1+cnt2+1;
int s=0;
for(int i=1;i<=n;i++) {
int u=id1[i],v=id2[i];
if (a[i]!=i&&b[i]!=i) {
addEdge(u,cnt1+v,1);
if (a[i]==b[i]) addEdge(cnt1+v,u,1);
}
else if (a[i]!=i) addEdge(u,vt,1);
else if (b[i]!=i) addEdge(vs,cnt1+v,1);
else s++;
}
printf("%d\n",n-s-Flow::maxflow());
return 0;
}