-
- //求图中环的个数
- //由于图中每个点的出度只有1,所以不存在一个点处于两个环的交点
- //因此,求环的个数时每个只需要考虑一次便可得出结果
- //由于数据规模庞大,写成递归形式容易暴栈
- //在读边的过程中先对自环进行预处理,之后对每个点进行不同的染色,对它的下一个点也染同样的颜色
- //这样染下去如果发现下一个要染的点和正在染的颜色相同,则说明存在一个环
- //换染色起点的同时也需要更换新的染色,才能保证对环的判断正确
- #include<iostream>
- #include<cstring>
- using namespace std;
- int next[1000001];//指向下一结点的指针
- int vis[1000001];//对每个结点进行不同的标记
- int ans,n,ringID,p;
- void search()
- {
- for(int i = 1;i <= n;++i)
- {
- if(vis[i] > 0) continue;
- p = i;
- ++ringID;//对每一种环进行一种不同的标记,新的起点必须更换新的染色
- while(vis[p] == 0)//当前结点未被染色
- {
- vis[p] = ringID;//染色
- p = next[p];//指向下一个点
- if(vis[p] == ringID)//下一个点的颜色和当前染色相同,则说明存在一个环
- ++ans;
- }
- }
- }
- int main()
- {
- //freopen("in.txt","r",stdin);
- while(scanf("%d",&n) != EOF)
- {
- ans = 0;
- ringID = 1;
- memset(vis,0,sizeof(vis));
- for(int i = 1;i <= n;++i)
- {
- scanf("%d",&next[i]);
- if(next[i] == i)
- {
- vis[i] = ringID++;//先对自环进行预处理
- ans++;
- }
- }
- search();
- printf("%d/n",ans);
- }
- return 0;
- }
搜索|求图中环的个数)
最新推荐文章于 2019-12-09 01:08:32 发布