歡迎來看 “片” (的簡介)
由於-\(看片\)-生涯轉瞬即逝,於是我選擇對“\(片\)”進行一定的總結:
相信你一定看懂了
由於開始的時間有一點晚,就姑且認為我以後會慢慢補充吧......
回到總部
\(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
- 當發現可以建無向圖的時候,不妨再想一想能否用並查集