【luogu P2661 信息传递】 题解

题目链接:https://www.luogu.org/problemnew/show/P2661#sub

一种利用并查集求最小环的做法:

对于每个同学看作一个点,每次信息传递是一条有向边,当出现最小环的时候就是所求游戏轮数。

那么我们在并查集上进行一些改动,用dep数组来保存路径的长度,即轮数。

如果有两个点的父节点相同,即组成了一个环。

注意的是要开一个last变量记录父节点(不记录就会在递归中被更新)。

 #include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = ;
int fa[maxn], dep[maxn], n, ans = 0x7fffffff;
int find(int x)
{
if(fa[x]!=x)
{
int last = fa[x];
fa[x] = find(fa[x]);
dep[x] += dep[last];
}
return fa[x];
}
void check(int a,int b)
{
int x = find(a);
int y = find(b);
if(x!=y){fa[x] = y; dep[a] = dep[b]+;}
else ans = min(dep[a]+dep[b]+,ans);
return;
}
int main()
{
int a;
scanf("%d",&n);
for(int i = ; i <= n; i++) fa[i] = i;
for(int i = ; i <= n; i++)
{
scanf("%d",&a);
check(i,a);
}
printf("%d",ans);
}
上一篇:CSS will-change 属性


下一篇:第四十五节,logging日志模块