拓扑排序-利用优先队列

#include <cstdio>  
#include <vector>  
#include <queue>  
#include <algorithm>  
  
using namespace std;  
const int MAXN = 505;  
vector<int> Graph[MAXN];  
int TopNum[MAXN], NodeNum[MAXN];;  
int NumVertex, NumEdge;  
  
// 有向无环图一定存在拓扑序  
void TopoSort()  
{  
    // 维护入度为0的节点,编号从小到大排序,保证编号小的节点的拓扑序小  
    priority_queue<int, vector<int>, greater<int> > que;  
    // 将入度为0的节点加入队列  
    for(int i=1; i<=NumVertex; ++i)  
    {  
        if(Graph[i][0] == 0) que.push(i);  
    }  
    // 循环处理入度为0的节点,并赋予拓扑序  
    int cnt = 0;  
    while(!que.empty())  
    {  
        int u = que.top();  
        que.pop();  
        // 将最较小拓扑序号赋给入度为0且当前编号最小的节点  
        TopNum[u] = ++cnt;  
        // 删除节点u出发的边,并调整其它节点的入度  
        for(int i=1; i<Graph[u].size(); ++i)  
        {  
            // 将调整后入度为0的节点加入队列  
            if(--Graph[Graph[u][i]][0] == 0) que.push(Graph[u][i]);  
        }  
    }  
    // 图中存在环则无拓扑序  
    if(cnt != NumVertex) return;  
    // 如果图并不一定是全联通的,那么判原图的某一连通域中是否存在环:  
    for(int i=1; i<=NumVertex; ++i) if(Graph[i][0]) puts("somerwhere of the graph has a cycle");  
  
    // 输出以拓扑序排列的节点编号  
    for(int i=1; i<=NumVertex; ++i) NodeNum[TopNum[i]] = i;  
    for(int i=1; i<=NumVertex; ++i) printf("%d%c", NodeNum[i], i==NumVertex?'\n':' ');  
}  
  
int main()  
{//freopen("sample.txt", "r", stdin);  
    while(~scanf("%d%d", &NumVertex, &NumEdge))  
    {  
        // 初始化  
        for(int i=1; i<=NumVertex; ++i)  
        {  
            Graph[i].clear();  
            // 初始化入度  
            Graph[i].push_back(0);  
        }  
        // 建图  
        for(int i=1; i<=NumEdge; ++i)  
        {  
            int u, v;  
            scanf("%d%d", &u, &v);  
            // 使用邻接表时,重边对于拓扑序无影响,所以可以不用处理  
            //if(find(Graph[u].begin(), Graph[u].end(), v)  
            //   == Graph[u].end())  
            {  
                Graph[u].push_back(v);  
                // v节点的入度加1  
                ++Graph[v][0];  
            }  
        }  
        // 拓扑排序  
        TopoSort();  
    }  
    return 0;  
}  

 

posted @ 2018-02-04 09:24  ckxkexing  阅读(262)  评论(0编辑  收藏  举报