片 - 圖論 - 1

MilkingAnAloe發表於2024-07-27

歡迎來看 “片” (的簡介)

由於-\(看片\)-生涯轉瞬即逝,於是我選擇對“\(片\)”進行一定的總結:

相信你一定看懂了

由於開始的時間有一點晚,就姑且認為我以後會慢慢補充吧......

回到總部

\(B3609\) \([圖論與代數結構\) \(701]\) \(強連通分量\)

解:tarjan,強連通分量

\(\mathcal{RT}\)

點選檢視程式碼
#include <iostream>
#include <algorithm>
#include <vector>
#define ll long long
#define endl '\n'
using namespace std;
const int MAXM=1e5+5;
const int MAXN=1e4+5;
ll n,m;
struct edge{
	ll to,nxt;
};
edge e[MAXM];
ll head[MAXN],tot=0;
void add_edge(ll u,ll v){
	++tot;
	e[tot].to=v;
	e[tot].nxt=head[u];
	head[u]=tot;
}
ll colsum=0,dfn[MAXN],low[MAXN],stk[MAXN],vis[MAXN],dep=0,col[MAXN];
vector <ll> ans[MAXN];
void tarjan(ll u){
	dfn[u]=++dep;
	low[u]=dep;
	stk[++stk[0]]=u;
	vis[u]=1;
	for (int i=head[u];i;i=e[i].nxt){
		ll v=e[i].to;
		if (!dfn[v]){
			tarjan(v);
			low[u]=min(low[v],low[u]);
		}
		else{
			if (vis[v]){
				low[u]=min(low[v],low[u]);
			}
		}
	}
	if (low[u]!=dfn[u]){
		return;
	}
//	cout<<u<<endl;
	++colsum;
	vis[u]=0;
	ans[colsum].push_back(u);
	while (stk[stk[0]]!=u){
		vis[stk[stk[0]]]=0;
		ans[colsum].push_back(stk[stk[0]]);
		col[stk[stk[0]]]=colsum;
		--stk[0];
	}
	--stk[0];
	col[u]=colsum;
}
bool flag[MAXN];
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for (int i=1;i<=m;i++){
		ll u,v;
		cin>>u>>v;
		add_edge(u,v);
	}
	for (int i=1;i<=n;i++){
		if (!dfn[i]) tarjan(i);
	}
	for (int i=1;i<=colsum;i++){
		sort(ans[i].begin(),ans[i].end());
	}
	cout<<colsum<<endl;
	for (int i=1;i<=n;i++){
		if (!flag[col[i]]){
			for (auto a:ans[col[i]])
				cout<<a<<" ";
			flag[col[i]]=1;
			cout<<endl;
		}
		
	}
}

Tips

  1. 當發現可以建無向圖的時候,不妨再想一想能否用並查集

相關文章