toposort_bfs

/*
思想:选择入度为0的顶点输出,并且删除该顶点和图中所有出边循环结束后,如果输出
顶点个数小于图中顶点个数,则说明存在有向环。
时间/空间复杂度:O(n+m)/O(n*n)
应用:判有向环、topo排序
例题:FZU1924
*/
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,t;
queue<int>Q;
const int maxn=1100;
int G[maxn][maxn];
int indegree[maxn];
int topo[maxn];
bool toposort_bfs(){

    int num_v=0;            //记录入队顶点的个数
    t=0;                    //topo顺序下标
    while(!Q.empty()){

        Q.pop();
    }
    for(int i=0;i<n;i++){

        if(indegree[i]==0){ //将入度为0的顶点入队

            Q.push(i);
        }
    }
    while(!Q.empty()){

        int u=Q.front();
        Q.pop();
        topo[t++]=u;    //将排好顺序的顶点放入数组
        num_v++;        //记录入度为0的顶点个数
        for(int i=0;i<n;i++){

            if(G[u][i]){//如果有弧
                
                //将跟弧尾i的入度减一
                indegree[i]--;  
                if(indegree[i]==0)
                    Q.push(i);
            }
        }
    }
    if(num_v==n)    //可以形成拓扑顺序
        return true;    
    else            //不能
        return false;

}
int main(){

    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){

        int u,v;
        scanf("%d%d",&u,&v);
        G[u][v]=1;      //有向图
        indegree[v]++;  //记录入度
    }
    toposort_bfs();
    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 11:09  tcgoshawk  阅读(86)  评论(0编辑  收藏  举报