tarjan求有向图强连通分量
tarjan算法的简单应用
hdu1269
题目链接
题意
- 给定有向图,问改有向图是否只有一个强连通分量
思路
- tarjan算法求有向图强连通分量的简单应用
代码
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <cstddef>
#include <stack>
using i64 = long long;
using ll = long long;
const int N = 10005;
std::vector<int> g[N];
int n, m, low[N], num[N], id, cnt, sscid[N];
std::stack<int> st;
void dfs(int u) {
num[u] = low[u] = ++ id;
st.push(u);
for (unsigned int i = 0; i < g[u].size(); ++ i) {
int v = g[u][i];
if(!num[v]) {
dfs(v);
low[u] = std::min(low[u], low[v]);
} else if(!sscid[v]) {
low[u] = std::min(low[u], num[v]);
}
}
if(num[u] == low[u]) {
++ cnt;
while(1) {
int v = st.top();
st.pop();
sscid[v] = cnt;
if(v == u) break;
}
}
return;
}
void tarjan() {
for (int i = 1; i <= n; ++ i) {
if(!num[i]) {
dfs(i);
}
}
return;
}
void init() {
for (int i = 0; i < N; ++ i) g[i].clear();
std::memset(low, 0, sizeof(low));
std::memset(num, 0, sizeof(num));
std::memset(sscid, 0, sizeof(sscid));
id = 0;
cnt = 0;
return;
}
void slove() {
init();
for (int i = 1; i <= m; ++ i) {
int u, v;
std::cin >> u >> v;
g[u].push_back(v);
}
tarjan();
std::cout << (cnt == 1 ? "Yes\n" : "No\n");
return;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
while(std::cin >> n >> m, n || m) {
slove();
}
return 0;
}