题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1067
/*
* 参考:http://biaobiaoqi.me/blog/2013/10/08/pat-1065-pat-1068/
*
* 分析示例、找准方法: 把问题抽象为圈。
* dfs,并查集都可计算圈内元素个数。因此题结构简单,适合用dfs思想。
* 设一个圈有m个元素,包含0的圈需要执行m-1次swap,不包含0
* 的需要m+1次操作。
*/
#include <stdio.h>
#define SIZE 100000+10
int a[SIZE];
bool visit[SIZE];
int n;
int findLink(int x)
{
int count = 0;
while(visit[x] == false)
{
visit[x] = true;
count ++;
x = a[x];
}
return count;
}
int main()
{
scanf("%d", &n);
int i;
for(i=0; i<n; i++)
{
visit[i] = false;
}
// memset(visit, false, sizeof(visit));
for(i=0; i<n; i++)
{
scanf("%d", &a[i]);
}
int ans = 0;
for(i=0; i<n; i++)
{
int count = findLink(i); // count 圈中元素
/*
* count == 0 : 圈中无已访问
* count == 1 : 圈中仅一个元素,即元素已在正确位置
* 否则,权当0不在圈内计算,之后再判断结果。
*/
if(count == 0 || count == 1)
{
continue;
}
else
{
ans = ans + (count+1);
}
}
/*
* 因含0与不含0,操作查2次。
* 当某圈含0时,必多了2次操作。
*/
if(a[0] != 0) // 必有一圈中包含0,
{
ans = ans - 2;
}
printf("%d\n", ans);
return 0;
}