洛谷-P2661 信息传递——有向图中的最小环

题意

给定一个 $n$ 个结点有向图,求其中最小环的大小。($n \leq 200000$).

分析

由于每条点出度都为1且满足传递性,可以用并查集做。

如果有一条从x到y的有向边,那么y就是x的父亲。如果x,y在同一集合,说明x,y都在环上。还需维护每个结点到根节点的距离。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 200000 + 10;
int fa[maxn], dis[maxn];  //fa父节点
int n, ans;

//初始化n个节点
void init(int n)
{
    for (int i = 0; i <= n; i++)
        fa[i] = i;
}

//查询树的根
int find(int x)
{
    if (x == fa[x])  return fa[x];
    int father = fa[x];
    fa[x] = find(fa[x]);  //先递归更新dis 
    dis[x] += dis[father];
    return fa[x];
}

//合并x和y所属的集合
void unite(int x, int y)   //x-->y
{
    int rx = find(x);
    int ry = find(y);
    if (rx == ry)
    {
        ans = min(ans, dis[x]+dis[y]+1);
    }
    else
    {
        fa[rx] = ry;
        dis[x] = dis[y] + 1;
    }
}

int main()
{
    scanf("%d", &n);
    init(n);
    ans = maxn+1;
    for(int i = 1;i <= n;i++)
    {
        int u;
        scanf("%d", &u);
        unite(i, u);
    }
    printf("%d\n", ans);
    return 0;
}

 

 

参考链接:https://www.cnblogs.com/wyboooo/p/11057090.html

上一篇:[luogu2571][bzoj1857][SCOI2010]传送门【三分套三分】


下一篇:C++ 图的存储结构及遍历