1. 程式人生 > >HDU 1269 -- 迷宮城堡【有向圖求SCC的數目 && 模板】

HDU 1269 -- 迷宮城堡【有向圖求SCC的數目 && 模板】

-a tom 一行 art 建立 div mil printf out

迷宮城堡

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9893 Accepted Submission(s): 4433


Problem Description 為了訓練小希的方向感,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
有向圖求SCC的裸題

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 10000 + 100
#define maxm 100000 + 1000
using namespace std;
int n, m;
struct node {
	int u, v, next;
};
node edge[maxm];
int head[maxn], cnt;
int low[maxn], dfn[maxn];
int dfs_clock;
int Stack[maxn];
bool Instack[maxn];
int top;
int Belong[maxn] , scc_clock;

void init(){
	cnt = 0;
	memset(head, -1, sizeof(head));
}

void addedge(int u, int v){
	edge[cnt] = {u, v, head[u]};
	head[u] = cnt++;
}

void getmap(){
    while(m--){
        int a, b;
        scanf("%d%d", &a, &b);
        addedge(a, b);
    }
}

void tarjan(int u, int per){
    int v;
    low[u] = dfn[u] = ++dfs_clock;
    Stack[top++] = u;
    Instack[u] = true;
    int have = 1;
    for(int i = head[u]; i != -1; i = edge[i].next){
        v = edge[i].v;
        if(v == per && have){
            have = 0;
            continue;
        }
        if(!dfn[v]){
            tarjan(v, u);
            low[u] = min(low[v], low[u]);
        }
        else if(Instack[v]){
            low[u] = min(low[u], dfn[v]);
        }
    }
    if(dfn[u] == low[u]){
        scc_clock++;
        do{
            v = Stack[--top];
            Instack[v] = false;
            Belong[v] = scc_clock;
        }while(u != v);
    }
}

void find(){
    memset(low, 0, sizeof(low));
    memset(dfn, 0, sizeof(dfn));
    memset(Instack, false, sizeof(Instack));
    memset(Belong, 0, sizeof(Belong));
    dfs_clock = scc_clock = top = 0;
    for(int i = 1; i <= n; ++i){
        if(!dfn[i])
            tarjan(i, i);
    }
}

void solve(){
    if(scc_clock == 1)
        printf("Yes\n");
    else
        printf("No\n");
}

int main (){
	while(scanf("%d%d", &n, &m), n || m){
        init();
        getmap();
        find();
        solve();
	}
	return 0;
}


HDU 1269 -- 迷宮城堡【有向圖求SCC的數目 &amp;&amp; 模板】