jr求助边双连通分量,调了一下午了,现35分。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 5, M = 5e5 + 5;
typedef pair<int, int> PII;
int n, m, low[N], dfn[N], scc, cnt, cut[N * 2], col[N], bh;
vector<PII> g[N];
vector<int> ans[N];
void tarjan(int now, int fa) {
dfn[now] = low[now] = ++scc;
for(PII u : g[now]) {
if(!dfn[u.first]) {
tarjan(u.first, now);
low[now] = min(low[now], low[u.first]);
if(low[u.first] > dfn[now]) cut[u.second] = cut[u.second ^ 1] = 1;
}
else if(u.first != fa) low[now] = min(low[now], dfn[u.first]);
}
}
void dfs(int now) {
col[now] = cnt;
if(now) ans[cnt].push_back(now);
for(PII u : g[now]) {
if(col[u.first] || cut[u.second]) continue;
dfs(u.first);
}
}
int main(){
cin >> n >> m;
for(int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
if(u == v) continue;
g[u].push_back({v, ++bh});
g[v].push_back({u, ++bh});
}
for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i, 0);
for(int i = 1; i <= n; i++) if(!col[i]) cnt++, dfs(i);
cout << cnt << endl;
for(int i = 1; i <= cnt; i++) {
cout << ans[i].size() << ' ';
for(int u : ans[i]) cout << u << ' ';
puts("");
}
return 0;
}