• 有向图强连通分支的Tarjan算法讲解 + HDU 1269 连通图 Tarjan 结题报告


    题目很简单就拿着这道题简单说说 有向图强连通分支的Tarjan算法

    有向图强连通分支的Tarjan算法伪代码如下:
    void Tarjan(u) {
    dfn[u]=low[u]=++index//进行DFS,每发现一个新的点就对这个点打上时间戳,所以先找到的点时间戳越早,dfn[U]表示最早发现u的时间,low[u]表示u能到达的最早的时间戳。
    stack.push(u)//将U压入栈中
    for each (u, v) in E {
    if (v is not visted)//如果V点没有经历过DFS,则对V点进行搜索

    {
    tarjan(v)
    low[u] = min(low[u], low[v]) //因为U和V连接,所以V能到达的最早的时间戳,U一定可以到达,比较后取小值。
    }
    else if (v in stack)//如果V点已经在栈中了,那么比较dfn[V]和low[u]后取小值

    {
    low[u] = min(low[u], dfn[v])
    }
    }
    if (dfn[u] == low[u]) { //u是一个强连通分量的根
    repeat
    v = stack.pop
    print v
    until (u== v)
    } //退栈,把整个强连通分量都弹出来
    } //复杂度是O(E+V)的

    下面贴出HDU1269的代码,这是道很基础的模板题。

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    #define INF 0xfffffff
    #define MAX 101000
    
    using namespace std;
    
    int n,m,k,Time,vis[MAX],low[MAX],dfn[MAX],black,e,Stack[MAX];
    
    vector<vector<int> >G;
    
    void Tarjan(int u)
    {
        vis[u]=1;
        Stack[++k]=u;
        low[u]=dfn[u]=Time++;
    
        int v,len=G[u].size(),i;
    
        for(i=0;i<len;i++)
        {
            v=G[u][i];
    
            if(!dfn[v])
            {
                Tarjan(v);
                low[u]=min(low[u],low[v]);
            }
    
            else if(vis[v])
            {
                low[u]=min(low[u],dfn[v]);
            }
        }
    
        if(dfn[u]==low[u])
        {
            do
            {
                v=Stack[k--];
                e++;
                vis[v]=0;
            }while(u!=v);
            black++;
        }
    }
    
    int main()
    {
        int i,j,a,b;
    
        while(scanf("%d%d",&n,&m),n+m)
        {
            Time=1;
            k=e=black=0;
            memset(vis,0,sizeof(vis));
            memset(low,0,sizeof(low));
            memset(dfn,0,sizeof(dfn));
            memset(Stack,0,sizeof(Stack));
    
            G.clear();
            G.resize(n+1);
    
            for(i=1;i<=m;i++)
            {
                scanf("%d%d",&a,&b);
                G[a].push_back(b);
            }
    
            Tarjan(1);
    
            if(e==n && black==1)
                printf("Yes
    ");
            else
                printf("No
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    dba_segments和dba_tables的不同
    查询用户表空间
    远程登录Oracle数据库
    SQL Server 收缩数据库
    Xshell乱码解决方法设置
    Spring常用注解
    Hibernate的fetch
    在 Eclipse 中使用 JSHint 检查 JavaScript 代码
    enterprise architect (EA) 源码生成UML类图,帮助理解项目工程
    上传excel数据到数据库中
  • 原文地址:https://www.cnblogs.com/alan-W/p/5672040.html
Copyright © 2020-2023  润新知