题目:有向图中,点的个数为n,边的个数为m,接下来有m行,每行输入u,v,表示u到v节点有一条有向边。
求强连通分量代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<set>
using namespace std;
const int MAXN = 1005;
const int INF = 0x7fffffff;
vector<int> adj[MAXN];
int dfn[MAXN];
int low[MAXN];
int index;
stack<int> st;
bool vis[MAXN];
/*
* 找强连通分量的Tarjan
*/
void Tarjan(int u){
dfn[u] = low[u] = ++index;
st.push(u);
vis[u] = true;
for(int i=0;i<adj[u].size();i++){
int v = adj[u][i];
if(dfn[v] == 0){ //说明V点没有搜索过
Tarjan(v);
low[u] = min(low[u],low[v]);
}else if(vis[v]){ //说明V点已经搜索过了,而且还在栈中
low[u] = min(low[u],dfn[v]);
}
}
if(dfn[u] == low[u]){
int v = -1;
do{
v = st.top();
st.pop();
vis[v] = false;
cout<<v<<" ";
}while(u != v);
cout<<endl;
}
}
void TarjanTravel(int n){
for(int i=1;i<=n;i++){
if(dfn[i] == 0){
Tarjan(i);
}
}
}
int main(){
int n,m;
int u,v;
cin>>n>>m;
while(m--){
cin>>u>>v;
adj[u].push_back(v);
// adj[v].push_back(u);
}
TarjanTravel(n);
return 0;
}
测试数据:
6 6
1 2
2 3
3 5
5 4
4 2
5 6
输出结果:
6
4 5 3 2
1