牛客-NOIP信息传递——并查集解决最小环问题
Posted C+++++++++++++++++++
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客-NOIP信息传递——并查集解决最小环问题相关的知识,希望对你有一定的参考价值。
题目
题目详解
上面的手写已经很详细了,我这里做个总结:
这是一个最小环问题。
此法限制条件:每个点的出度必须为1(方便计算环里面的结点个数)
具体做法:
-
用并查集思路做每条边的连接。
//TODO 并查集的查找动作,查找的同时记一波数 int find(int i,int& cnt) cnt++; if(i==f[i])return i; return find(f[i],cnt);//TODO 注意为了方便每次能查找根结点的同时计算这个环上的元素个数,所以不要去路径压缩! ... f[i] = dst;//TODO 由于数据给出i的传递对象是dst,所以把i的出度设为dst ...
-
一旦出现连接dst会产生环,则更新环的大小(这里利用所有元素出度为1的性质简化了判环和计算环元素个数的过程)。
//TODO 并查集的查找动作,查找的同时记一波数 int find(int i,int& cnt) cnt++; if(i==f[i])return i; return find(f[i],cnt);//TODO 注意为了方便每次能查找根结点的同时计算这个环上的元素个数,所以不要去路径压缩! ... if(find(dst,cnt)==i)//TODO 一旦产生出度为0的点连接了他的子节点(只要这个结点的根结点是i,则这个结点时i的子节点),则产生环 ret = min(cnt,ret); ...
解题代码
#include<bits/stdc++.h>
#define MAXN 200005
using namespace std;
int f[MAXN];
//TODO 并查集的查找动作,查找的同时记一波数
int find(int i,int& cnt)
cnt++;
if(i==f[i])return i;
return find(f[i],cnt);
int main()
ios::sync_with_stdio(false);
int n;
cin>>n;
for(int i=1;i<=n;i++)
f[i] = i;
int ret = INT_MAX;
for(int i=1;i<=n;i++)
int dst,cnt = 0;
cin>>dst;
if(find(dst,cnt)==i)//TODO 一旦产生出度为0的点连接了他的子节点则产生环
ret = min(cnt,ret);
else//TODO 没有产生环则,正常连接
f[i] = dst;
cout<<ret;
return 0;
以上是关于牛客-NOIP信息传递——并查集解决最小环问题的主要内容,如果未能解决你的问题,请参考以下文章