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

*/

  

posted @ 2015-03-23 10:17  tcgoshawk  阅读(151)  评论(0编辑  收藏  举报