链接https://atcoder.jp/contests/arc097/tasks/arc097_b
题意 给你一个排列
然后给你M个pair,这两个pair位置的值可以互换,
然后问你最多能换成多少个位置的pi=i;
题解:
手玩了一下,发现你连起来的pair,可以互换成全排列,
然后这就是个并查集的问题了,
合并他们能到达的位置的集合,
每次查询当前并查集里的位置能不能达到就可以了
然后学了一下合并两个vector的函数
#include<bits/stdc++.h> //#include<tr1::unordered_map> #define rep(i,a,n) for(int i=a;i<=n;++i) #define per(i,a,n) for(int i=n;i>=a;--i) #define pb push_back #define fi first #define se second #define io std::ios::sync_with_stdio(false) using namespace std; typedef long long ll; typedef pair<int,int> pii; const int P = 1e9+7, INF = 0x3f3f3f3f; const int maxn=1e5+10; ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; } ll qpow(ll a,ll n) { ll r=1%P; for (a%=P; n; a=a*a%P,n>>=1)if(n&1)r=r*a%P; return r; } int fa[maxn]; vector<int> ans[maxn]; int a[maxn]; int findfa(int x) { if(fa[x]==x) return x; else return fa[x]=findfa(fa[x]); } int main() { io; int n,m; cin>>n>>m; for(int i=1;i<=n;i++) {cin>>a[i]; fa[i]=i; ans[i].push_back(i);//肯定能到达自己,方便合并 } while(m--) { int x,y; cin>>x>>y; int t=findfa(x); int tt=findfa(y); if(t==tt) continue; if(ans[t].size()>ans[tt].size()) { ans[t].insert(ans[t].end(),ans[tt].begin(),ans[tt].end());//合并操作 fa[tt]=t; ans[tt].clear(); } else { ans[tt].insert(ans[tt].end(),ans[t].begin(),ans[t].end()); fa[t]=tt; ans[t].clear(); } } int sum=0; for(int i=1;i<=n;i++) sort(ans[i].begin(),ans[i].end()); for(int i=1;i<=n;i++) { if(a[i]==i) { sum++; continue; } int f=findfa(i); int id=lower_bound(ans[f].begin(),ans[f].end(),a[i])-ans[f].begin(); if(id<ans[f].size()&&ans[f][id]==a[i]) { sum++; } } cout<<sum<<endl; }