链接
https://pintia.cn/problem-sets/994805342720868352/problems/994805402305150976
题解
众所周知,一个置换对应的图一定是若干个基本环
对于一个包含
0
0
0的环,假设大小为
k
(
k
>
1
)
k(k>1)
k(k>1),那么我需要花
k
−
1
k-1
k−1次交换才能使之变成目标状态
对于一个不包含
0
0
0的环,假设其大小为
k
(
k
>
1
)
k(k>1)
k(k>1),我需要先花费
1
1
1次交换把
0
0
0添加到这个环中,然后再花
k
+
1
−
1
=
k
k+1-1=k
k+1−1=k次交换使之变成目标状态
代码
#include <bits/stdc++.h>
#define maxn 100010
#define iinf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3fll
#define ll long long
using namespace std;
ll f[maxn], g[maxn], N, cnt, ans, vis[maxn], d;
ll read(ll x=0)
{
ll c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
void init()
{
ll i;
N = read();
for(i=0;i<N;i++)
{
f[i] = read();
g[f[i]]=i;
}
}
void dfs(ll pos)
{
cnt++;
if(pos==0)d=-1;
vis[pos]=true;
if(!vis[g[pos]])dfs(g[pos]);
}
int main()
{
ll i;
init();
for(i=0;i<N;i++)
if(!vis[i])
{
cnt=0;
d=1;
dfs(i);
if(cnt>1)ans+=cnt+d;
}
printf("%lld",ans);
return 0;
}