代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e5 + 5;
vector<int> ans[MAXN];
int dfn[MAXN], low[MAXN], visited[MAXN];
int head[MAXN], ver[MAXN * 2], Next[MAXN * 2];
int num = 0;
int root, dcc, tot;
bool bridge[MAXN];
void add(int x, int y) {
ver[++tot] = y;
Next[tot] = head[x];
head[x] = tot;
}
void tarjan(int i, int in_edge) {
dfn[i] = low[i] = ++num;
for(int j = head[i]; j ; j = Next[j]) {
int v = ver[j];
if(!dfn[v]) {
tarjan(v, j);
low[i] = min(low[i], low[v]);
if(low[v] > dfn[i]) {
bridge[i] = bridge[i ^ 1] = true;
}
}else if(i != (in_edge ^ 1)) low[i] = min(low[i], dfn[v]);
}
}
void dfs(int i) {
visited[i] = dcc;
if(i) ans[dcc].push_back(i);
for(int j = head[i]; j ; j = Next[j]) {
int v = ver[j];
if(visited[v] || bridge[j]) continue;
dfs(v);
}
}
int main() {
int n, e;
cin >> n >> e;
for(int i = 1; i <= e; i++) {
int u, v;
cin >> u >> v;
if(u == v) continue;
add(u, v);
add(v, u);
}
for(int i = 1; i <= n; i++) {
if(!dfn[i]) {
root = i;
tarjan(i, 0);
}
}
for(int i = 1; i <= n; i++) {
if(!visited[i]) {
++dcc;
dfs(i);
}
}
cout << dcc << endl;
for(int i = 1; i <= dcc; i++) {
cout << ans[i].size() << " ";
for(int j = 0; j < ans[i].size(); j++) {
cout << ans[i][j] << " ";
}
cout << endl;
}
return 0;
}