社区讨论

关于tarjan

学术版参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@m42v9619
此快照首次捕获于
2024/11/29 22:56
去年
此快照最后确认于
2025/11/04 13:38
4 个月前
查看原帖
RT,这个代码输出的 SCC 缩点后总是一个合法的拓扑序。(参考题目
bug or feature
CPP
vector<int> gv[500001], scc[500001];
stack<int> st;

int dfn[500001], low[500001], ins[500001], cnt = 0, tot = 0, n, m;

inline void add_edge(int u, int v){
	gv[u].push_back(v);
}

void Tarjan(int u){
	dfn[u] = low[u] = ++tot;
	st.push(u); ins[u] = 1;
	for(auto v : gv[u]){
		if(dfn[v] && ins[v])
			low[u] = min(low[u], dfn[v]);
		else if(!dfn[v]){
			Tarjan(v);
			low[u] = min(low[u], low[v]);
		}
	}
	if(low[u] == dfn[u]){
		cnt++; int x = st.top();
		do{
			scc[cnt].push_back(x = st.top());
			ins[st.top()] = 0;
			st.pop();
		}while(x != u);
	}
}

void init_vars(){
	// type your initiating code...
}

void solve(int testcase, ...){
	init_vars();
	cin >> n >> m;
	for(int i = 1; i <= m; i++){
		int u, v; cin >> u >> v;
		u++, v++;
		add_edge(u, v);
	}
	for(int i = 1; i <= n; i++){
		if(!dfn[i]) Tarjan(i);
	}
	cout << cnt << endl;
	for(int i = cnt; i >= 1; i--){
		cout << scc[i].size() << " ";
		for(auto x : scc[i])
			cout << x - 1 << " ";
		cout << endl;
	}
}

回复

2 条回复,欢迎继续交流。

正在加载回复...