赞
踩
背景:给定若干个节点,每个节点都指向另一个节点或者指向自己,判断这若干个点形成的环的个数
注意:勿要认为是求连通块问题,因为环中各点形成的结构是没有出口的,没有根节点
例题:
acwing 1224.交换瓶子
有 N个瓶子,编号 1∼N,放在架子上。
比如有 5个瓶子:
2 1 3 5 4
要求每次拿起 2 个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换 2 次就可以复位。
如果瓶子更多呢?你可以通过编程来解决。
输入格式
第一行包含一个整数 N,表示瓶子数量。
第二行包含 N 个整数,表示瓶子目前的排列状况。
输出格式
输出一个正整数,表示至少交换多少次,才能完成排序。
数据范围
1≤N≤10000,
输入样例1:
5 3 1 2 5 4输出样例1:
3
输入样例2:
5 5 4 3 2 1输出样例2:
2
代码:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
-
- const int N=10010;
-
- int a[N];
- bool st[N];
- int n;
-
- int main()
- {
- scanf("%d",&n);
- for(int i=1;i<=n;i++) scanf("%d",&a[i]);
-
- int cnt=0;
- for(int i=1;i<=n;i++)
- {
- if(st[i]) continue;
- cnt++;
-
- for(int j=i;!st[j];j=a[j]) st[j]=true;
- }
-
- printf("%d\n",n-cnt);
-
- return 0;
- }

解释:
让每个节点指向它们应该放置的位置,由此形成若干个环。
经过模拟可以发现,由n个节点构成的环中,至少交换n-cnt次就可以使得环中各个节点放置在正确的位置,并且消除掉这个环。
因此节点总数-环的数量就是应该交换的次数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。