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;
}

posted @ 2023-02-04 12:08  lemonsbiscuit  阅读(10)  评论(0编辑  收藏  举报