迷宮城堡 HDU - 1269 (塔尖算法求強連通分量)

爲了訓練小希的方向感,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

思路:塔尖模板求 強連通分量 。此題是判斷所有的點能否構成 一個強連通分量

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int fir[100010],nex[100010],to[100010];
int col,tot,top,num;
int co[100010];
int dfn[100010];
int low[100010];
int a[100010];
int build(int x,int y)//鄰接表
{
    to[++tot]=y;
    nex[tot]=fir[x];
    fir[x]=tot;
}
void tarjan(int u)//塔尖算法的核心
{
    dfn[u]=low[u]=++num;
    a[++top]=u;
    for(int i=fir[u]; i>0; i=nex[i])
    {
        int v=to[i];
        if(dfn[v]==0)
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else
        {
            if(!co[v])
                low[u]=min(low[u],dfn[v]);
        }
    }
    if(low[u]==dfn[u])
    {
        co[u]=++col;
        while(a[top]!=u)
        {
            co[a[top]]=col;
            --top;
        }
        --top;
    }
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)
            break;
        memset(fir,0,sizeof(fir));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(co,0,sizeof(co));
        memset(to,0,sizeof(to));
        memset(a,0,sizeof(a));
        int x,y;
        tot=0,col=0,top=0;
        for(int i=0; i<m; i++)
        {
            scanf("%d%d",&x,&y);
            build(x,y);
        }
        for(int i=1; i<=n; i++)
            if(!dfn[i])
                tarjan(i);
        if(col==1)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章