procedure Strongly_Connected_Components(G);
- begin
- 1.深度优先遍历G,算出每个结点u的结束时间f[u],起点如何选择无所谓。
- 2.深度优先遍历G的转置图GT,选择遍历的起点时,按照结点的结束时间从大到小进行。遍历的过程中,一边遍历,一边给结点做分类标记,每找到一个新的起点,分类标记值就加1。
- 3. 第2步中产生的标记值相同的结点构成深度优先森林中的一棵树,也即一个强连通分量
- end;
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=10000+10;
bool vis[maxn];
int ID[maxn]; //点的颜色编号
int ncolor;
vector<int> s;
vector<vector<int> > color(maxn); //同一种颜色的点
vector<vector<int> > G(maxn);
vector<vector<int> > GT(maxn);
void dfs(int u){vis[u]=true;for(int i=0;i<G[u].size();i++){int v=G[u][i];if(!vis[v]) dfs(v);}s.push_back(u);
}
void dfs2(int u){vis[u]=true;ID[u]=ncolor;color[ncolor].push_back(u);for(int i=0;i<GT[u].size();i++){int v=GT[u][i];if(!vis[v]) dfs2(v);}
}
void Korasaju(int n)
{memset(vis,false,sizeof(vis));s.clear();for(int i=1;i<=n;i++) if(!vis[i]) dfs(i);memset(vis,false,sizeof(vis));ncolor=0;for(int i=s.size()-1;i>=0;i--) {int j=s[i];if(!vis[j]) ncolor++,dfs2(j);}
}
int main()
{int n,m;cin>>n>>m;while(m--){int u,v;cin>>u>>v;G[u].push_back(v);GT[v].push_back(u); //转置图 }Korasaju(n);return 0;
}