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
  • 相关阅读:
    git .gitignore不生效的解决方法
    python 爬虫中常需要睡眠防止被封IP time sleep
    Python 实现字典操作详解
    Python遍历字典到列表中出现覆盖前面数据或者字典对值(值为列表)赋值出现重复的问题
    小红书app之shield 逆向
    淘宝h5 页面 sign加密算法
    jemter-base64加密
    Python 中更优雅的日志记录方案
    logging再学习
    elasticsearch中must和should条件同时满足
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8412504.html
Copyright © 2011-2022 走看看