poj 1674

随便看到的一个题

题目:http://poj.org/problem?id=1674

给出 n 个数,问最小的交换次数可以让这 n 个数变成升序排列的

这个一开始还以为dp呢,可是想了好长时间也不知道怎么dp,原来是找给的n个数里的环的问题,比如说样例 2 

2 3 5 4 1 这里面有两个环 {2,3,5,1},{4},2应该在的位置是 3,3应该在的位置是 5,5应该在的位置是 1,然后1 就到 2 了,所以就是一个环,然后最小的交换次数就是 n - 环数

View Code
 1 const int N = 10010;
 2 struct node
 3 {
 4     int x;
 5     int id;
 6 }a[N];
 7 bool vis[N];
 8 int main()
 9 {
10     int i,j;
11     int t,n;
12     //freopen("data.txt","r",stdin);
13     scanf("%d",&t);
14     while(t--)
15     {
16         _clr(vis,0);
17         scanf("%d",&n);
18         int flag = 0;
19         int sum;
20         for(i = 1; i <= n; i++)
21         {
22             scanf("%d",&a[i].x);
23             if(i != a[i].x) flag = 1;
24             a[i].id = i;
25         }
26         if(!flag)
27         {
28             printf("0\n");
29             continue;
30         }
31         sum = 0;
32         for(i = 1; i <= n; i++)
33         {
34             flag = 0;
35             int temp = a[i].x;
36             if(!vis[i]) sum ++;
37             if(i != temp && !vis[i])
38             {
39                 //sum ++;
40                 vis[temp] = 1;
41                 while(i != temp)
42                 {
43                    flag = 1;
44                    temp = a[temp].x;
45                    vis[temp] = 1;
46                 }
47             }
48         }
49         printf("%d\n",n - sum);
50     }
51     return 0;
52 }
原文地址:https://www.cnblogs.com/fxh19911107/p/2648144.html