hdu1269 有向图强连通 Targan(模板)

Posted 00isok

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu1269 有向图强连通 Targan(模板)相关的知识,希望对你有一定的参考价值。

<题目链接>

题目大意:

为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间。Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i。 

Input

输入包含多组数据,输入的第一行有两个数:N和M,接下来的M行每行有两个数a和b,表示了一条通道可以从A房间来到B房间。文件最后以两个0结束。 
Output

对于输入的每组数据,如果任意两个房间都是相互连接的,输出"Yes",否则输出"No"。 
Sample Input

3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0

Sample Output

Yes
No

解题分析:
有向图求强连通分量的裸题,下面用的是Targan算法。

#include <cstdio>
#include <cstring>

const int maxn=100000+100;

struct EDGE{
    int next;
    int to;
}edge[maxn];

int n,m,cnt,top,sumlink;
int head[maxn];
int dfn[maxn];
int vis[maxn],Stack[maxn];
int low[maxn];

int min(int a,int b){return a<b?a:b;}

void add(int u,int v){      //链式前向星构图
    edge[++cnt].next=head[u];
    edge[cnt].to=v;
    head[u]=cnt;
}

void INIT(){        //初始化
    memset(dfn,0,sizeof(dfn));
    memset(head,-1,sizeof(head));
    memset(vis,0,sizeof(vis));
    cnt=0;      //遍历的时间坐标
    top=0;      //栈中的元素个数
    sumlink=0;  //连通分量的个数
}

void Targan(int u){
    if(sumlink>1)return;       //如果连通分量>1,说明不符合题意,直接结束
    dfn[u]=low[u]=++cnt;    //dfn为遍历的序号
    Stack[++top]=u;         //入栈
    vis[u]=true;          //标记该点在栈里

    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(!dfn[v]){       //如果这个点没有遍历过
            Targan(v);        
            low[u]=min(low[u],low[v]);        
        }        
        else if(vis[v]){    //如果这个点在栈中        
            low[u]=min(low[u],dfn[v]);         
        }
    }

    if(dfn[u]==low[u]){     //如果找到了这个连通分量的根节点
        sumlink++;       //连通分量数量+1
        while(true){
            int temp=Stack[top];
            vis[temp]=0;
            --top;          //及时将该连通块在栈中的点排出,配合vis[]数组,能够使同一连通块的low值相同,而不是这个联通块的值等于它之前遍历到的连通块的low值
            if(temp==u)     //将该连通块中的根节点搜索完后(根节点==该连通块最早被dfs到的点==该连通块在栈的最底部的点)
                break;
        }
    }
}


int main(){
    while(scanf("%d %d",&n,&m)!=EOF,n|m){
        INIT();
        for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d %d",&u,&v);
            add(u,v);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i])
                Targan(i);
        }

        if(sumlink==1){
            printf("Yes
");
        }
        else
            printf("No
");
    }
    return 0;
}



2018-08-16











以上是关于hdu1269 有向图强连通 Targan(模板)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1269 迷宫城堡 tarjan算法求强连通分量

HDU1269迷宫城堡(裸Tarjan有向图求强连通分量个数)

HDU-1269-迷宫城堡(强连通 模板)

hdu1269:强连通分量

poj2186 强连通分量 targan算法的应用

HDU 1269:迷宫城堡(强连通)