HDU-1269-迷宫城堡(强连通 模板)
链接:https://vjudge.net/problem/HDU-1269
题意:
为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间。Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i。
思路:
求图的强连通分量, tarjan算法
代码:
#include <iostream> #include <memory.h> #include <cstdio> #include <map> #include <string> #include <cstring> #include <vector> #include <set> #include <algorithm> using namespace std; typedef long long LL; const int MAXN = 1e4+10; vector<int> G[MAXN]; int Dfn[MAXN], Low[MAXN]; int n, m; int sum, times; void Tarjan(int x) { Dfn[x] = Low[x] = ++times; for (auto node:G[x]) { if (Dfn[node] == 0) { Tarjan(node); Low[x] = min(Low[x], Low[node]); } else { Low[x] = min(Low[x], Dfn[node]); } } if (Dfn[x] == Low[x]) sum++; } bool Check() { for (int i = 1;i <= n;i++) if (Dfn[i] == 0) return false; return true; } int main() { while (cin >> n >> m) { for (int i = 1;i <= n;i++) G[i].clear(); memset(Dfn, 0, sizeof(Dfn)); memset(Low, 0, sizeof(Low)); sum = 0, times = 0; if (n == 0 && m == 0) break; int l, r; for (int i = 1;i <= m;i++) { cin >> l >> r; G[l].push_back(r); } Tarjan(1); if (sum == 1 && Check()) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }