1067 Sort with Swap(0, i) (25 分)
Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order. But what if Swap(0, *)
is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the following way:
Swap(0, 1) => {4, 1, 2, 0, 3}
Swap(0, 3) => {4, 1, 2, 3, 0}
Swap(0, 4) => {0, 1, 2, 3, 4}
Now you are asked to find the minimum number of swaps need to sort the given permutation of the first N nonnegative integers.
Input Specification:
Each input file contains one test case, which gives a positive N (≤105) followed by a permutation sequence of {0, 1, ..., N−1}. All the numbers in a line are separated by a space.
Output Specification:
For each case, simply print in a line the minimum number of swaps need to sort the given permutation.
Sample Input:
10
3 5 7 2 6 4 9 0 8 1
Sample Output:
9
经过演算发现有 0 的环是 n-1 没0的环是n+1当然了 个数要大于等于2才行
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int digit[maxn], pre[maxn];
int cnt[maxn];
int find(int x){
if(x == pre[x])
return x;
return pre[x] = find(pre[x]);
}
void merge(int x, int y)
{
int fx = find(x);
int fy = find(y);
if(fx != fy){
pre[fx] = fy;
}
}
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
for(int i = 0; i < n ; i++)
{
cin>>digit[i];
pre[i] = i;
}
for(int i = 0 ; i < n; i ++)
merge(i , digit[i]);
for(int i = 0; i < n; i ++)
cnt[find(i)] ++;
int gg = cnt[find(0)];
int kk = find(0);
int ans = 0;
if(gg != 1) //表明不是digit[0] = 0
ans = gg - 1;
for(int i = 0 ; i < n ; i++)
{
if(cnt[i] == 1 || i == kk || cnt[i] == 0)
continue;
ans = ans + cnt[i] + 1;
}
cout<<ans<<endl;
return 0;
}