zoukankan      html  css  js  c++  java
  • 拓扑排序-利用优先队列

    #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?'
    ':' ');  
    }  
      
    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;  
    }  
    skr
  • 相关阅读:
    ​DBEngines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
    深入了解 BTree 和 B+Tree 的区别
    exec详解
    javascript之property's attributes
    极客公园之李彦宏讲话要点
    C++之auto_ptr
    javascript之属性状态控制Method
    ARM寄存器简介
    linux之fcntl
    http之100continue
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8412504.html
Copyright © 2011-2022 走看看