强连通分量之Tarjan算法

概念

强联通:如果有向图中两个点vi和vj,其中vi到vj之间有一条有向路径,vj到vi有一条有向路径,则称vi,vj强联通。
强连通图:如果有向图G<V,E>中每两个点都强联通,则称该图是强连通图。
强连通分量:有向图的极大强联通子图称为强连通分量。

Tarjan算法的思想

  首先,介绍tarjan关键的两个数组dfn和low。dfn[i]记录该点被dfs的时间,low[i]记录该点所在的深度优先搜索树中的根节点的编号。在执行过程中需要栈来保存深度优先所遍历的节点并确定这些节点所处的强连通分量。
  其中low的更新规则是:如果当前点u的某一邻边的另一个端点v未被访问过,则low[u]=min(low[u],low[v]);如果v点被访问过并且v一定在栈中,则low[u]=min(low[u],dfn[v])。

Tarjan算法的实现(HDU-1269)

#include <iostream>
#include <vector>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <stack>
using namespace std;
const int maxn=10010;
const int maxm=100010;
vector<int> g[maxn];
int visit[maxn];
int dfn[maxn];
int low[maxn];
bool inStack[maxn];
int n,m,time;
int res;
int ans[maxn];
stack<int> st;
void init(int n0)
{
    memset(visit,0,sizeof(visit));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(ans,0,sizeof(ans));
    for(int i=0;i<=n0;i++)
    {
        g[i].clear();
    }
    while(!st.empty())
    {
        st.pop();
    }
    time=0;
    res=0;
}

void verjan(int i0)
{
    low[i0]=dfn[i0]=time++;
    st.push(i0);
    inStack[i0]=true;
    visit[i0]=1;
    for(int i=0;i<g[i0].size();i++)
    {
        int v=g[i0][i];
        if(visit[v]==0)
        {
            verjan(v);
            low[i0]=min(low[i0],low[v]);

        }else if(inStack[v])
        {
            low[i0]=min(low[i0],dfn[v]);
        }
    }
    if(dfn[i0]==low[i0])
    {
        int v0;
        do
        {
            v0=st.top();
            st.pop();
            inStack[v0]=0;
            ans[res]++;
        }while(v0!=i0);
         res++;
    }

}

int main()
{
    scanf("%d%d",&n,&m);
    while(n!=0||m!=0)
    {
        init(n);
        for(int i=0;i<m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            g[a].push_back(b);
        }
        verjan(1);
        if(ans[0]==n)
        {
            printf("Yes\n");
        }
        else
        {
            printf("No\n");
        }
        scanf("%d%d",&n,&m);

    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 强连通分量 概念 1.连通:在有向图中,若存在点a到达点b的有向路径并且存在点b到达点a的有向路径,则点a和点b是...
    Bin_ZH阅读 1,065评论 0 0
  • iOS面试题分享群:群号:129018636 1.使用了第三方库, 有看它们是怎么实现的吗? 2.强连通量算法了解...
    MUYO_echo阅读 401评论 0 0
  • Linux文件权限 33574977dr-xr-x---. 2 root root 196 Mar5 17:21 ...
    puurutsjdy阅读 238评论 0 0
  • 晴天的日子, 你的心里有了阳光。 雨天的日子, 你的心里有了清凉。 梦想的日子, 你的心里有了目标。 你现在是这样...
    小剧在成长阅读 145评论 0 3
  • 又一个第二天。每个早起就发现好像将一天延长了,用自己的生活方式去改变自己。 是的,我不喜欢现在这个物欲横流,什么都...
    阿紫0707阅读 152评论 0 0