D - Equals
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 400400 points
Problem Statement
We have a permutation of the integers from 11 through NN, p_1p1, p_2p2, .., p_NpN. We also have MM pairs of two integers between 11 and NN (inclusive), represented as (x_1,y_1)(x1,y1), (x_2,y_2)(x2,y2), .., (x_M,y_M)(xM,yM). AtCoDeer the deer is going to perform the following operation on pp as many times as desired so that the number of ii (11 ≤≤ ii ≤≤ NN) such that p_i = ipi=i is maximized:
- Choose jj such that 11 ≤≤ jj ≤≤ MM, and swap p_{x_j}pxj and p_{y_j}pyj.
Find the maximum possible number of ii such that p_i = ipi=i after operations.
Constraints
- 22 ≤≤ NN ≤≤ 10^5105
- 11 ≤≤ MM ≤≤ 10^5105
- pp is a permutation of integers from 11 through NN.
- 11 ≤≤ x_j,y_jxj,yj ≤≤ NN
- x_jxj ≠= y_jyj
- If ii ≠= jj, \{x_i,y_i\}{xi,yi} ≠= \{x_j,y_j\}{xj,yj}.
- All values in input are integers.
Input
Input is given from Standard Input in the following format:
NN MM p_1p1 p_2p2 .... p_NpN x_1x1 y_1y1 x_2x2 y_2y2 :: x_MxM y_MyM
Output
Print the maximum possible number of ii such that p_i = ipi=i after operations.
Sample Input 1 Copy
Copy
5 2 5 3 1 4 2 1 3 5 4
Sample Output 1 Copy
Copy
2
If we perform the operation by choosing j=1j=1, pp becomes 1 3 5 4 2
, which is optimal, so the answer is 22.
Sample Input 2 Copy
Copy
3 2 3 2 1 1 2 2 3
Sample Output 2 Copy
Copy
3
If we perform the operation by, for example, choosing j=1j=1, j=2j=2, j=1j=1 in this order, pp becomes 1 2 3
, which is obviously optimal. Note that we may choose the same jj any number of times.
Sample Input 3 Copy
Copy
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 Copy
Copy
8
Sample Input 4 Copy
Copy
5 1 1 2 3 4 5 1 5
Sample Output 4 Copy
Copy
5
简单图论题,直接拿出我的并查集模板,直接拿捏!
上代码!
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e6;
int pre[N];
int find(int x){
if(pre[x]==x){
return x;
}
return pre[x]=find(pre[x]);
}
void join(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx!=fy){
pre[fx]=fy;
}
}
int p[N];
int x[N];int y[N];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
int main(){
for(int i=1;i<N;++i)pre[i]=i;
int n,m;cin>>n>>m;
for(int i=1;i<=n;++i)p[i]=read();
for(int i=1;i<=m;++i){
x[i]=read();y[i]=read();
join(x[i],y[i]);
}
int ans=0;
for(int i=1;i<=n;++i){
if(find(p[i])==find(p[p[i]]))ans++;
}
cout<<ans<<endl;return 0;
}