鸡(chicken)
鸡(chicken)题解
题目描述
给定一个排列 p,每次可以交换 p_i, p_j,交换的代价是 |p_i - p_j|。
在完成所有交换后,小鸡会开始走路,记当前小鸡所在的点是 i,小鸡下一步会走到 p_i。小鸡从1开始走,你需要保证小鸡若干步后能走遍所有的点并回到1。
请求出达成目标的最小代价。
解题思路
因为要从图中任意一点i出发,并走遍所有点,后而回到i,让我们发现这很像一个环。
接着看样例
4
3 1 2 4
发现图中3 1 2构成一个环,4自已单独一个,而合并这两个环的最小代价就是交换3,4
后可推导出每个环都一定可以找到一个代价为1的环进行合并
所以这题就只用找到图中有几个环(联通快),把环的数量-1就是操作次数也就是代价
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n;
int a[N],fa[N];
int fi(int x){
if(fa[x]!=x) fa[x]=fi(fa[x]);
return fa[x];
}
int main(){
cin >> n;
for(int i=1;i<=n;i++) cin >> a[i];
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=n;i++){
int fx=fi(a[i]);
int fy=fi(a[a[i]]);
if(fx!=fy){
fa[fx]=fy;
}
}
int sum=0;
for(int i=1;i<=n;i++){
if(fa[i]==i) ++sum;
}
cout << sum-1;
return 0;
}

浙公网安备 33010602011771号