我本来用 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;
}
}