HDU 4857 逃生(拓扑排序)

                                            拓扑排序

一.定义

    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前。

   通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。

   注意:

   1)只有有向无环图才存在拓扑序列;

   2)对于一个DAG,可能存在多个拓扑序列(此题已经规定了数字的优先级,所以答案唯一);

 

二.拓扑序列算法思想

 (1)从有向图中选取一个没有前驱(即入度为0)的顶点,并输出之;

 

 (2)从有向图中删去此顶点以及所有以它为尾的弧;

     重复上述两步,直至图空,或者图不空但找不到无前驱的顶点为止。
 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include<functional>
#define MAXSIZE 100005
using namespace std;

vector<int>G[MAXSIZE];
priority_queue<int ,vector<int>, less<int> > q;
int in[MAXSIZE];

int main()
{
    int T,n,m,a,b;
    scanf("%d",&T);
    while(T--)
    {
        memset(in,0,sizeof(in));
        vector<int> ans;
        for(int i=0;i<MAXSIZE;i++)
            G[i].clear();
        scanf("%d%d",&n,&m);
        while(m--)
        {
            scanf("%d%d",&a,&b);
            in[a]++;
            G[b].push_back(a);
        }
        for(int i=1;i<=n;i++)
            if(!in[i]) q.push(i);
        while(!q.empty())
        {
            int u=q.top();
            ans.push_back(u);
            q.pop();
            int len=G[u].size();
            for(int i=0;i<len;i++)
            {
                int v=G[u][i];
                in[v]--;
                if(!in[v])
                    q.push(v);
            }

        }
        int len=ans.size();
        for(int i=len-1;i>=0;i--)
            printf("%d%c",ans[i],i==0?'\n':' ');
    }
    return 0;
}
View Code

 

posted @ 2017-03-29 15:28  声声醉如兰  阅读(349)  评论(0编辑  收藏  举报