1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 500010, M = 4000010;
int n, m; int h[N], e[M], ne[M], idx; int dfn[N], low[N], timestamp; int stk[N], top, cnt; vector<int> edcc[N]; int root;
void add(int a, int b) {e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;}
void tarjan(int u, int edge) { dfn[u] = low[u] = ++ timestamp; if(u == root && h[u] == -1) { edcc[++ cnt].push_back(u); return; } stk[ ++ top] = u; for(int i = h[u]; ~i; i = ne[i]) { int ver = e[i]; if(!dfn[ver]) { tarjan(ver, i); low[u] = min(low[u], low[ver]); } else if(i != (edge ^ 1)) low[u] = min(low[u], dfn[ver]); } if(dfn[u] == low[u]) { cnt ++ ; while(stk[top] != u) edcc[cnt].push_back(stk[top -- ]); edcc[cnt].push_back(stk[top -- ]); } }
int main() { memset(h, -1, sizeof h); scanf("%d%d", &n, &m); for(int i = 1; i <= m; i ++ ) { int a, b; scanf("%d%d", &a, &b); if(a == b) continue; add(a, b), add(b, a); } for(root = 1; root <= n; root ++ ) { if(dfn[root]) continue; tarjan(root, -1); } printf("%d\n", cnt); for(int i = 1; i <= cnt; i ++ ) { printf("%lld", edcc[i].size()); for(auto ver : edcc[i]) printf(" %d", ver); printf("\n"); } return 0; }
|