D - Equals

D - Equals

Problem Statement
We have a permutation of the integers from 1 through$ N, p_1, p_2, .., p_N$. We also have \(M\) pairs of two integers between \(1\) and$ N $(inclusive), represented as \((x_1,y_1),(x_2,y_2), .., (x_M,y_M).\) AtCoDeer the deer is going to perform the following operation on p as many times as desired so that the number of $i (1 ≤ i ≤ N) $such that pi=iis maximized:

Choose j such that \(1 ≤ j ≤ M\), and swap \(pxj\) and \(pyj\).
Find the maximum possible number of i such that pi=i after operations.

Constraints
\(2 ≤ N ≤ 10^5\)
\(1 ≤ M ≤ 10^5\)
p is a permutation of integers from \(1\) through \(N\).
\(1 ≤ x_j,y_j ≤ N\)
\(x_j ≠ y_j\)
If \(i ≠ j, {x_i,y_i} ≠ {x_j,y_j}.\)
All values in input are integers.
Input
Input is given from Standard Input in the following format:

N M
p1 p2 .. pN
x1 y1
x2 y2
:
xM yM
Output
Print the maximum possible number of i such that pi=i after operations.

Sample Input 1
5 2
5 3 1 4 2
1 3
5 4
Sample Output 1
2
If we perform the operation by choosing j=1, p becomes 1 3 5 4 2, which is optimal, so the answer is 2.

Sample Input 2
3 2
3 2 1
1 2
2 3
Sample Output 2
3
If we perform the operation by, for example, choosing j=1, j=2, j=1 in this order, p becomes 1 2 3, which is obviously optimal. Note that we may choose the same j any number of times.

Sample Input 3
10 8
5 3 6 8 7 10 9 1 2 4
3 1
4 1
5 9
2 5
6 5
3 5
8 9
7 9
Sample Output 3
8
Sample Input 4
5 1
1 2 3 4 5
1 5
Sample Output 4
5
We do not have to perform the operation.

题意

通过无限次操作\(m\)个可交换的位置最多可以使多少个\(p_i = i\)

思路

将可以交换的位置用并查集合成一个集合,遍历一遍数组,如果\(dad[i]\)\(p_i\)在一个集合中,则ans+1

代码

点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;

#define X first
#define Y second

typedef pair<int,int> pii;
typedef long long LL;
const char nl = '\n';
const int N = 2e5+10;
const int M = 2e5+10;
int n,m;
int a[N],p[N];

int find(int x){
	if(p[x] != x)p[x] = find(p[x]);
	return p[x];
}

void solve(){
	cin >> n >> m;
	for(int i = 1; i <= n; i ++ ){
		cin >> a[i];
		p[i] = i;
	}
	while(m --){
		int a,b;
		cin >> a >> b;
		p[find(a)] = find(b);
	}
	int ans = 0;
	for(int i = 1; i <= n; i ++ ){
		if(find(i) == find(a[i]))ans ++;
	}
	cout << ans << nl;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);

	solve();
}
posted @ 2023-02-22 21:56  Keith-  阅读(13)  评论(0编辑  收藏  举报