HDU1269-Tarjan演算法
阿新 • • 發佈:2018-12-11
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
|
AC_CODE:
#include <bits/stdc++.h> #define N 11000 #define M 110000 using namespace std; struct EDG { int u, v, nxt; }edg[M]; int head[N], dfn[N], low[N], v[N], q[N], cnt, scnt, top, n, m, blong[N]; void init() { memset(head, 0, sizeof(head)); memset(dfn, 0, sizeof(dfn)); cnt = top = scnt = 0; } void tarjan(int u) { int t; dfn[u] = low[u] = m++; v[u] = 1; q[top++] = u; for (int i = head[u]; i; i = edg[i].nxt) { int c = edg[i].v; if (!dfn[c]) { tarjan(c); } low[u] = min(low[u], low[c]); } if (dfn[u] == low[u]) { scnt++; do { t = q[--top]; v[t] = 0; blong[t] = scnt; } while (t != u); } } void solve() { for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i); } int main() { while (~scanf("%d%d", &n, &m) && (n || m)) { init(); for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); edg[i] = { u,v,head[u]}; head[u] = i; } solve(); cout << (scnt == 1 ? "Yes" : "No") << endl; } }