zoukankan      html  css  js  c++  java
  • 图上求最小环

    最近做了道水题题,信息传递,题目要求就是求出有向图的最小环。

    做完乍一看题解有好多好多种办法,在此整理一下。

    我对于这道题的做法是:

    由于每个点最多连出一条边,所以可能存在两个环相连的情况,所以对于入度为0的点删掉就好,然后不断删不断删,

    直到删到图上仅有环,就一个一个求一求环的大小,取最小的那一个。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define maxn 200005
     6 
     7 using namespace std;
     8 
     9 int nxt[maxn],ans=2147483647,ind[maxn],n;
    10 bool vis[maxn];
    11 
    12 inline void cancel(int k)
    13 {
    14     int e=nxt[k];
    15     ind[k]=0; ind[nxt[k]]--; nxt[k]=-1;
    16     if(ind[e]==0) cancel(e);
    17 }
    18 
    19 inline void dfs(int x_now,int st,int len)
    20 {
    21     if(x_now==st&&len!=0)
    22     {
    23         vis[x_now]=true;
    24         ans=min(ans,len);
    25         return;
    26     }
    27     else
    28     {
    29         vis[nxt[x_now]]=true;
    30         dfs(nxt[x_now],st,len+1);
    31     }
    32     return;
    33 }
    34 
    35 int main()
    36 {
    37     scanf("%d",&n);
    38     for(int i=1;i<=n;i++)
    39     {
    40         scanf("%d",&nxt[i]);
    41         ind[nxt[i]]++;
    42     }
    43     for(int i=1;i<=n;i++)
    44         if(ind[i]==0&&nxt[i]!=-1) cancel(i);
    45     for(int i=1;i<=n;i++)
    46         if(nxt[i]!=-1&&!vis[i]) dfs(i,i,0);
    47     printf("%d
    ",ans);
    48     return 0;
    49 }

    一开始我还想用缩点求每个强连通分量的大小,后来一想,强联通分量是极大的子图,所以对于大环中有小环的情况,它只能求出

    大环而求不出小环。

    例如:

    所以这种愚蠢的想法就被pass了。


    还有一种做法就是用带权并查集做,权维护的是该点到自己父节点的距离。

    如果某一条边连接了两个父节点相同的点,说明它们构成环,环的大小是...,

  • 相关阅读:
    Android相对布局中控件的常用属性【转】
    Android:仿微信设置菜单
    Android:scrollview与listview共存
    感想12.26
    (C#)GDI+绘制垂直文字
    10.14 近期小结
    学习C++的忠告
    C# TCP学习笔记
    C#读书笔记(4)—重学数组
    近期学习计划 12.23
  • 原文地址:https://www.cnblogs.com/Hoyoak/p/11380313.html
Copyright © 2011-2022 走看看