其实这道题是置换群的入门题,看起来就是一个裸的DFS+统计,处理数组C[i]的时候类似时间戳的正反的处理方式。总之就是比较玄学吧。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1000005;
long long vis[N],a[N],b[N],c[N],n,w[N],tot,num,minn,mint=0x3f3f3f3f;
long long ans;
template<class T>inline void read(T &res){
static char ch;T flag=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
void dfs(int u){
++num,tot+=w[a[u]],vis[u]=1;
minn=min(minn,w[a[u]]);
if(vis[c[b[u]]])return ;
dfs(c[b[u]]);
}
int main(){
read(n);
for(register int i=1;i<=n;i++)read(w[i]),mint=min(mint,w[i]);
for(register int i=1;i<=n;i++)read(a[i]),c[a[i]]=i;
for(register int i=1;i<=n;i++)read(b[i]);
for(register int i=1;i<=n;i++){
minn=0x3f3f3f3f;tot=num=0;
if(vis[i])continue;
else dfs(i);
ans+=min(minn*(num-2)+tot,mint*(num+1)+minn+tot);
}
cout<<ans<<endl;
return 0;
}