主题思想: 图论 ,判断一个图是否是强联通,以及求图的强联通分量。
判断一个图是否是强联通的,有两种算法,一个是kosaraju 算法,和 tarjan 算法,
kosaraju是一个需要建立逆图的算法,这里介绍tarjan算法
核心思想是依据DFS. 更新LOW[i] 。
具体参考博客:
http://blog.csdn.net/w571523631/article/details/77990705
https://www.byvoid.com/zhs/blog/scc-tarjan
tarjan 代码:
int LOW[maxn];
int DFN[maxn];
int belong[maxn];
bool instack[maxn];
vector<int> g[maxn]; //
int Index=0;
int bnt=0;
int n,m;
stack<int> st;
void tarjan(int i){
DFN[i]=LOW[i]=++Index;
instack[i]=true;
st.push(i);
int len=g[i].size();
for(int j=0;j<len;j++){
// DFN[i] stands for the n-th that visited ,if DFN[i] is 0 means not visited;
if(!DFN[g[i][j]]){
tarjan(g[i][j]);
//LOW[i]=min(LOW[i],LOW[g[i][j]]);
if(LOW[i]>LOW[g[i][j]]) LOW[i]=LOW[g[i][j]];
}else if(instack[g[i][j]]&&LOW[i]>DFN[g[i][j]]){
LOW[i]=DFN[g[i][j]];
}
}
//
if(LOW[i]==DFN[i]){
bnt++;
int tmp;
while(st.top()!=i){
tmp=st.top();
belong[tmp]=bnt;
instack[tmp]=false;
st.pop();
}
if(st.top()==i){
st.pop();
belong[i]=bnt;
instack[i]=false;
}
}
}
bool solve(){
bnt=0;
Index=0;
//init
while(!st.empty())st.pop();
for(int i=0;i<=n;i++){
DFN[i]=0;
LOW[i]=0;
instack[i]=false;
belong[i]=0;
}
for(int i=1;i<=n;i++){
if(!DFN[i]){
tarjan(i);
}
}
//
if(bnt==1) return true;
else return false;
}
AC代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=10005;
int LOW[maxn];
int DFN[maxn];
int belong[maxn];
bool instack[maxn];
vector<int> g[maxn]; //
int Index=0;
int bnt=0;
int n,m;
stack<int> st;
void tarjan(int i){
DFN[i]=LOW[i]=++Index;
instack[i]=true;
st.push(i);
int len=g[i].size();
for(int j=0;j<len;j++){
// DFN[i] stands for the n-th that visited ,if DFN[i] is 0 means not visited;
if(!DFN[g[i][j]]){
tarjan(g[i][j]);
//LOW[i]=min(LOW[i],LOW[g[i][j]]);
if(LOW[i]>LOW[g[i][j]]) LOW[i]=LOW[g[i][j]];
}else if(instack[g[i][j]]&&LOW[i]>DFN[g[i][j]]){
LOW[i]=DFN[g[i][j]];
}
}
//
if(LOW[i]==DFN[i]){
bnt++;
int tmp;
while(st.top()!=i){
tmp=st.top();
belong[tmp]=bnt;
instack[tmp]=false;
st.pop();
}
if(st.top()==i){
st.pop();
belong[i]=bnt;
instack[i]=false;
}
}
}
bool solve(){
bnt=0;
Index=0;
//init
while(!st.empty())st.pop();
for(int i=0;i<=n;i++){
DFN[i]=0;
LOW[i]=0;
instack[i]=false;
belong[i]=0;
}
for(int i=1;i<=n;i++){
if(!DFN[i]){
tarjan(i);
}
}
//
if(bnt==1) return true;
else return false;
}
int main()
{
int a,b;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0&&m==0) break;
for(int i=0;i<=n;i++) g[i].clear();
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
g[a].push_back(b);
}
//solve to judge whether is strong connected graph or not
bool ans=false;
ans=solve();
if(ans)printf("Yes\n");
else printf("No\n");
}
return 0;
}