toposort_dfs
/*
思想:在toposort()函数中,深搜各个未访问的顶点,如果深搜返回的值为0
说明存在有向环。深搜中,正在访问的点u标记为-1,然后找弧尾v。如果c[v]<0
说明目前已找到的弧形成了有向环。再者如果弧尾v未访问过且深搜v返回值为
0,说明子集中存在有向环。
时间/空间复杂度:O(n)/O(n*n)
应用:有向图判环、有向排序
例题:FZU1924
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxv=1000;
int c[maxv];
//c[u]==0,表示未访问过,c[u]==1,表示访问过,c[u]==-1,表示正在栈帧中
int G[maxv][maxv];//矩阵存图
int topo[maxv]; //记录拓扑排序的顺序
int n,t;
bool dfs(int u){
c[u]=-1; //正在访问
for(int v=0;v<n;v++){
if(G[u][v]){
if(c[v]<0){
//存在有向环,顶点v在栈帧中
return false;
}else if(!c[v]&&!dfs(v)){
//顶点v的子集中有环
return false;
}
}
}
c[u]=1;
topo[--t]=u;
return true;
}
bool toposort_dfs(){
t=n;
memset(c,0,sizeof(c)); //清空标记
for(int u=0;u<n;u++){
if(!c[u]){
if(!dfs(u)){
return false; //不能拓扑排序,存在有向环
}
}
}
return true; //能拓扑排序
}
int main(){
int m;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
int u,v;
scanf("%d%d",&u,&v);
G[u][v]=1; //有向图
}
toposort_dfs();
for(int i=0;i<n;i++)
printf("%d\n",topo[i]);
return 0;
}
/*
7 8
0 2
0 1
1 2
1 5
5 6
2 3
2 4
3 4
*/
学学学 练练练 刷刷刷

浙公网安备 33010602011771号