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 */
学学学 练练练 刷刷刷