基环树找环模板

//无向图
int idx = 0;
bool found = false;
vector<int> loop,dfn(n + 1, 0), fa(n + 1, 0);
function<void(int)> dfs = [&](int u) {
	dfn[u] = ++idx;
	for (int v : e[u]) {
		if (v == fa[u]) {
			continue;
		}
		if (!dfn[v]) {
			fa[v] = u;
			dfs(v);
			if (found) {
				return;
			}
		}
		else if (dfn[v] < dfn[u]) {
			int cur = u;
			while (cur != v) {
				loop.push_back(cur);
				cur = fa[cur];
			}
			loop.push_back(v);
			found = true;
			return;
		}
	}
};
dfs(1);

//有向图
vector<int> loop, fa(n + 1, -1);
vector<int> vis(n + 1, 0); // 0: 未访问, 1: 访问中, 2: 已访问
int mark = -1;
function<bool(int)> dfs = [&](int u) -> bool {
	vis[u] = 1;
	for (int v : e[u]) {
		if (vis[v] == 0) {
			fa[v] = u;
			if (dfs(v)) {
				return true;
			}
		}
		else if (vis[v] == 1) {
			mark = v; // 找到环
			fa[v] = u;
			return true;
		}
	}
	vis[u] = 2;
	return false;
};
dfs(1);

if (mark != -1) {
	for (int v = fa[mark]; v != mark; v = fa[v]) {
		loop.push_back(v);
	}
	loop.push_back(mark);
	reverse(loop.begin(), loop.end());// 反转顺序,使环的顺序正确
}
posted @ 2025-09-11 13:56  Ke_scholar  阅读(14)  评论(1)    收藏  举报