Tarjan另一种实现方式过不了重边自环
查看原帖
Tarjan另一种实现方式过不了重边自环
231022
1234567890regis楼主2025/6/14 19:10

我本来用 Tarjan+dfs 过了这道题,今天来写和强联通分量基本一样的实现方式(好写!)。

但是这样写 WA 了,但只错了 6 个数据点,50pts。

我下载了哈克:

in:
5 7
4 2
5 4
4 2
3 2
1 2
1 1
2 1
out:
3
1 3
1 5
3 1 2 4
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#define int long long
using namespace std;

const int MAXN = 4e6 + 7;
int x[MAXN], y[MAXN], dfn[MAXN], low[MAXN], vis[MAXN], tm;

vector<vector<int>> bcc;
vector<int> to[MAXN], stk;

void Tarjan(int idx, int fa)
{
	dfn[idx] = low[idx] = ++tm;
	stk.push_back(idx); vis[idx] = 1;
	for (int i : to[idx])
	{
		if (i == fa) continue;
		if (!dfn[i]) Tarjan(i, idx), low[idx] = min(low[idx], low[i]);
		else if (vis[i]) low[idx] = min(low[idx], dfn[i]);
	}
	if (dfn[idx] == low[idx]) {
		vector<int> ret;
		ret.push_back(idx);
		while (stk.back() != idx)
			ret.push_back(stk.back()), vis[stk.back()] = false, stk.pop_back();
		stk.pop_back(); bcc.push_back(ret);
	}
}

signed main()
{
	int n, m; cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		int u, v; cin >> u >> v;
		if (u == v) continue;
		to[u].push_back(v), to[v].push_back(u);
	}
	for (int i = 1; i <= n; i++) {
		for (int j : to[i])
			cout << j << ' ';
		cout << endl;
	}
	for (int i = 1; i <= n; i++)
		if (!dfn[i])
			Tarjan(i, 0);
	cout << bcc.size() << '\n';
	for (int i = 0; i < bcc.size(); i++) {
		cout << bcc[i].size() << ' ';
		for (int j : bcc[i])
			cout << j << ' ';
		cout << endl;
	}
}
2025/6/14 19:10
加载中...