【训练题】拓扑排序

来源:互联网 发布:领导人媒体形象优化 编辑:程序博客网 时间:2024/05/18 17:59

【问题描述】
有N个士兵,编号依次为1,2,3,…,N, 队列训练时,指挥官要把一些士兵从高到矮依次排成一行。但现在指挥官不能直接获得每个人的身高信息,只能获得“p1比p2高”这样的比较结果:记为p1>p2。例如1>2,2>4,3>4。士兵的身高关系如图所示:
  
【输入格式】
第一行:包含两个整数N、M,第二至第M+1行:每行两个整数x,y,代表士兵x比士兵y高。

【输出格式】
一个1..N的排列,表示排队方案(字典序最小),如果没有可行方案则输出-1。

【输入样例】
【样例1】

4 31 22 43 4

【样例2】

4 41 22 42 33 1

【输出样例】
【样例1】

1 2 3 4

【样例2】

-1

【数据范围】
1<=N<10000
1<=M<=100000

/*    Name: Directed_Acyclic_Graph    Copyright: Twitter & Instagram @stevebieberjr    Author: @stevebieberjr    Date: 08/07/16 22:17*/#include<cstdio>#include<vector>#include<queue>#include<cstring>#define maxn 10005using namespace std;int rd[maxn],N,M;vector<int>g[maxn];void init(){    scanf("%d%d",&N,&M);    memset(rd,0,sizeof(rd));    int u,v;    for(int i=1;i<=M;i++)    {        scanf("%d%d",&u,&v);        g[u].push_back(v); //存储由u指向v的边         rd[v]++; //v的入度加1    }}struct mycmp{    bool operator () (int a,int b)    {        return a>b;    }}; //优先队列排序,值大的优先级低 vector<int>topo; //拓扑数组 bool toposort(){    priority_queue<int,vector<int>,mycmp>pq;    for(int i=1;i<=N;i++)    {        if(rd[i]==0) pq.push(i);    } //将入度为0(即无前驱)的结点加入队列进行BFS     while(!pq.empty())    {        int i=pq.top(); pq.pop();        topo.push_back(i);        for(int k=0;k<g[i].size();k++) //遍历i指向的所有结点        {            int j=g[i][k];            rd[j]--; //结点j的入度去掉i->j这条边            if(rd[j]==0) pq.push(j);        }    }    if(topo.size()<N) return 0; //存在环(即有结点入度永远不为0)     return 1;}int main(){    init();    if(toposort()==0) printf("-1\n");    else //输出拓扑数组     {        for(int i=0;i<topo.size();i++)        {            printf("%d ",topo[i]);        }    }    return 0;}
0 0
原创粉丝点击