zoukankan      html  css  js  c++  java
  • HDU1285 裸的拓扑排序

    拓扑排序:

    拓扑排序是应用于有向无回路图(DAG)上的一种排序方式,对一个有向无回路进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u在v的前面。该序列说明了顶点表示的事件或 状态发生的整体顺序。

    比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时可以以工程为顶点,工程间的依赖关系为边建立图,用拓扑排序来求得所有工程的合理执行顺序。

    对一个DAG进行拓扑排序有两种方法,广度优先搜索和深度优先搜索

    这里介绍广度优先搜索,进行拓扑排序时,每次可以拿出的顶点一定是入度为0的点,即没有被指向的点,因为这样的点表示的事件没有依赖,在一个入度为0的点表示的事件执行完之后,它所指向的顶点所依赖的点就少了一个,所以我们可以先将所有入度为0的点加入一个队列中,然后依次将它们所指向的点的入度减1,再将入度变为0的点也依次加入队列中,这样最后就可以得到一个拓扑有序的序列。

    本题中说符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前,需要用到优先队列,每次从队列中取的是最小的那个元素

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    const int maxn=510;
    int graph[maxn][maxn];//保存图
    int degree[maxn];//保存入度
    
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            memset(graph,0,sizeof(graph));
            memset(degree,0,sizeof(degree));
            for(int i=0;i<m;i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                if(!graph[u][v])
                {
                    graph[u][v]=1;
                    degree[v]++;//v的入度++
                }
            }
            priority_queue<int,vector<int>,greater<int> >q;
            for(int i=1;i<=n;i++)
                if(degree[i]==0)
                q.push(i);
            bool first=1;
            while(!q.empty())
            {
                int cur=q.top();
                q.pop();
                if(first)
                {
                    cout<<cur;
                    first=0;
                }
                else
                    cout<<" "<<cur;
                for(int i=1;i<=n;i++)
                {
                    if(graph[cur][i])
                    {
                        degree[i]--;//相连的点的入度减1
                        if(degree[i]==0)//如果入度为0,加入队列
                            q.push(i);
                    }
                }
            }
            printf("
    ");
        }
        return 0;
    }
    /**
     * The Kahn's Topological Sort Algorithm in C++
     * Using the Adjecency List
     * Time Cost : O(|V|+|E|)
     * Author: Zheng Chen / Arclabs001
     * Copyright 2015 Xi'an University of Posts & Telecommunications
     */
    #include <iostream>
    #include <queue>
    #include <vector>
    using namespace std;
    
    const int N = 5; // The number of Vertex
    
    enum status {UNDISCOVERED,VISITED};
    
    struct Vertex
    {
        int inDegree, outDegree;
        int data;
        status _stat;
    }V[N];
    
    vector<int> AdjList[N];   //Using vector to simulate the adjlist
    queue<int> vertexQueue;   //The call queue
    /**
     * Initialize the graph as below:
    The Graph:
    
    0->1->3
    |  |  |
    / / /
    2->4<--
    
     * @return The pointer to the start vertex
     */
    Vertex* init_graph()
    {
        while(!vertexQueue.empty())
            vertexQueue.pop();
    
        for(int i=0; i<N; i++)
        {
            AdjList[i].clear();
            V[i]._stat = UNDISCOVERED;
            V[i].data = i;
        }
    
        V[0].inDegree = 0; V[0].outDegree = 2;
        V[1].inDegree = 1; V[1].outDegree = 3;
        V[2].inDegree = 1; V[2].outDegree = 1;
        V[3].inDegree = 1; V[3].outDegree = 1;
        V[4].inDegree = 3; V[4].outDegree = 0;
    
        AdjList[0].push_back(1); AdjList[0].push_back(2);
        AdjList[1].push_back(3); AdjList[1].push_back(4);
        AdjList[2].push_back(4);
        AdjList[3].push_back(4);
    
        return & V[0];
    }
    
    bool Topological_Sort()
    {
        for(int i=0; i<N; i++)
        {
            if(V[i].inDegree == 0)
                vertexQueue.push(i);
        }
    
        while(!vertexQueue.empty())
        {
            int top = vertexQueue.front();
            V[top].outDegree = 0;
            V[top]._stat = VISITED;
            int i=0;
    
            for(int v : AdjList[top])
            {
                --V[v].inDegree;
    
                AdjList[top][i++] = -1;
                if(V[v].inDegree == 0)
                    vertexQueue.push(v);
            }
            cout<<top<<" ";
    
            vertexQueue.pop();
        }
    
        for(int i=0; i<N; i++)
        {
            for(int v : AdjList[i])
                if(v != -1)
                {
                    return false;
                }
        }
    
        return true;
    }
    
    int main()
    {
        init_graph();
    
        bool status = Topological_Sort();
        if(status == false)
        {
            cout<<"Error! The graph has at least one cycle!"<<endl;
        }
        return 0;
    }
  • 相关阅读:
    HDU 6071
    HDU 6073
    HDU 2124 Repair the Wall(贪心)
    HDU 2037 今年暑假不AC(贪心)
    HDU 1257 最少拦截系统(贪心)
    HDU 1789 Doing Homework again(贪心)
    HDU 1009 FatMouse' Trade(贪心)
    HDU 2216 Game III(BFS)
    HDU 1509 Windows Message Queue(队列)
    HDU 1081 To The Max(动态规划)
  • 原文地址:https://www.cnblogs.com/kimsimple/p/6875660.html
Copyright © 2011-2022 走看看