HDU1269 強連通分量-tarjan演算法
阿新 • • 發佈:2018-12-13
題意就是在給定一個圖的情況下,問這個單向圖是不是強連通圖。
強連通圖的意思就是圖中任何一個點都可以到達另一個點。
分析:這道題是tarjan演算法求強連通分量的模板題,對於tarjan演算法求連通分量的方法大致上是給每一個點標兩個號,一個是自己是第幾個被搜尋到i,也叫時間標號(程式碼中用dfn【i】來表示第i個點的標號),另一個是這個點的子樹中所能搜到的最小的時間標號(程式碼中用low【i】)表示,如果時間標號==low【i】那麼表示形成了一個聯通分量,具體的或者更加詳細的參考https://www.cnblogs.com/shadowland/p/5872257.html
再來說本題:要想證明一個圖是連通圖,則只需要證明整個圖只有一個連通分量即可;
程式碼:
#include<cstdio> #include<stack> #include<cstring> #include<algorithm> using namespace std; const int maxn = 1e4 + 10; const int maxm = 1e5 + 10; int cnt = 0; int ans = 0; int n, m; int head[maxn], dfn[maxn], low[maxn]; bool vis[maxn]; stack<int>iron; struct Edge { int from,to, next; }edge[maxm]; void addedge(int u, int v) { edge[cnt].from = u, edge[cnt].to = v; edge[cnt].next = head[u]; head[u] = cnt++; } void ini() { memset(head,-1,sizeof (head)); memset(dfn, 0, sizeof(dfn)); memset(vis, false, sizeof(vis)); memset(low, 0, sizeof(low)); cnt = ans = 0; } void dfs(int x) { dfn[x] = low[x] = ++cnt; iron.push(x); vis[x] = 1; for (int i = head[x]; ~i; i = edge[i].next) { int j = edge[i].to; if (!dfn[j]) dfs(j); low[x] = min(low[x], low[j]); } if (low[x] == dfn[x]) { ++ans; while (!iron.empty()) { int t = iron.top(); vis[t] = 0; iron.pop(); if (t == x) break; } } } void tarjin() { for (int i = 1; i <= n; i++) if (!dfn[i]) dfs(i); } int main() { while (scanf("%d %d", &n, &m) && n || m) { int u, v; ini(); for (int i = 0; i < m; i++) { scanf("%d %d", &u, &v); addedge(u, v); } cnt = 0; ans = 0; tarjin(); if (ans == 1) printf("Yes\n"); else printf("No\n"); } //system("pause"); return 0; }