求助边双连通分量
  • 板块灌水区
  • 楼主zeta炀
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/10/6 15:07
  • 上次更新2023/10/27 08:30:29
查看原帖
求助边双连通分量
466295
zeta炀楼主2022/10/6 15:07

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;
}
2022/10/6 15:07
加载中...