鸡(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;
}

posted @ 2026-07-10 09:36  zhangyirui  阅读(4)  评论(0)    收藏  举报