题目描述
松鼠宝宝有一排n个大小不一的坚果,松鼠宝宝想把坚果从小到大排序,每次他会选择两个坚果a和b每次花费1点力气把这两个坚果交换,爱动脑筋的松鼠宝宝想知道他排完这n个坚果一共需要花费的最少力气是多少?
输入描述:
第一行一个整数n代表坚果数
接下来一行n个整数代表每个坚果的大小(每个坚果大小都不一样,即大小为1-n的一个排列)
1<=n<=1e5
坚果大小x,1<=x<=n
输出描述:
一行输出代表松鼠宝宝花费的最小力气
示例1
输入
3 3 2 1
输出
1
居然是个并查集模板。。。。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=4e4+10;
const int N=1e5+10;
int minn=0x3f3f3f3f;
int maxn=0xc0c0c0c0;
int n,k,m;
int fa[N];
int a[N];
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
fa[i]=i;
for(int i=1;i<=n;i++)
{
cin>>a[i];
int fx=find(a[i]);
int fy=find(i);
if(fx!=fy)
fa[fx]=fy;
}
map<int,int> mp;
for(int i=1;i<=n;i++)
mp[find(i)]++;
cout<<n-mp.size()<<endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
ll t=1;
// cin>>t;
while(t--)
{
solve();
}
return 0;
}