码迷,mamicode.com
首页 > 编程语言 > 详细

拓扑排序-利用优先队列

时间:2018-02-04 11:23:01      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:name   node   scan   style   algorithm   begin   return   priority   can   

#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;  
}  

 

拓扑排序-利用优先队列

标签:name   node   scan   style   algorithm   begin   return   priority   can   

原文地址:https://www.cnblogs.com/ckxkexing/p/8412504.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!