NKOJ全TJ计划——NP5681

题目描述

果老师有一个 \(1\)\(n\) 的排列\(p_1,p_2,...,p_n\)

果老师给了你个\(m\)数对,\((x_1,y_1),(x_2,y_2),...,(x_m,y_m)\)

现在你可以选取任意对数\((x_i,y_i)\), 每个数对可以选取任意次, 然后使用选择的某对数进行操作,操作的方式为交换 \(p_{x_i}\)\(p_{y_i}\) 的位置。

最终你想要\(p_i=i\)的位置尽量多。输出最多可以有多少个这样的位置。

分析

每输入一个数对,就用并查集给它们绑在一起,然后如果\(i\)\(p_i\)被绑在一起,它们就一定可以通过把它们绑在一起的数对交换成如此状况。

代码(rhx:没有代码的TJ不是好TJ,不想给代码上TJ的作者不是好作者)

看前三问:你是为抄袭而来吗?你理解思路了吗?你需要代码吗?
#include<bits/stdc++.h>
using namespace std;
int n,m,a[100004],p[100004];
int i,j,b,c,ans=0;
int f(int a){
   	if(p[a]==a){
   		return a;
	}
	p[a]=f(p[a]);
	return p[a];
}
int main()
{
   	cin>>n>>m;
   	for(i=1;i<=n;i++) p[i]=i;
   	for(i=1;i<=n;i++) cin>>a[i];
   	for(i=1;i<=m;i++){
   		cin>>b>>c;
   		p[f(b)]=f(c);
   	}
   	for(i=1;i<=n;i++){
   		if(f(i)==f(a[i])){
   			ans++;
   		}
	}
	cout<<ans;
}
posted @ 2025-07-09 08:54  哈利·波特  阅读(7)  评论(0)    收藏  举报