这道题置换群裸题,对于一个置换群,交换所需代价为sum+min((tot-2)群里最小值,(tot+1)群里最小值+最小数);
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long b[1000005],ans,c[1000005],w[1000005];bool vis[1000005];
struct data
{
long long num;
int id;
}a[1000005];
long long mina(long long x,long long y)
{
return x<y?x:y;
}
int main()
{
int n;long long mininum=2000000000;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%lld",&w[i]);
mininum=mina(mininum,w[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i].num);
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&b[i]);
c[b[i]]=i;
}
for(int i=1;i<=n;i++)
{
a[i].id=c[a[i].num];
// cout<<a[i].id<<" "<<w[a[i].num]<<endl;
}
// cout<<mininum;
for(int i=1;i<=n;i++)
{
int tot=0;long long sum=0,minn=2000000000;
if(a[i].id==i||vis[i])
continue;
while(!vis[i])
{
sum+=w[a[i].num];
tot++;
minn=mina(minn,w[a[i].num]);
vis[i]=1;
i=a[i].id;
}
ans+=sum+mina((tot-2)*minn,minn+(tot+1)*mininum);
}
printf("%lld\n",ans);
}