HDU-#4857 逃生(拓扑排序)

来源:互联网 发布:江西安全知识网络答题 编辑:程序博客网 时间:2024/05/29 21:34

题目大意:给定N个人数的M组优先级关系,求编号小的尽量靠前的排队序列。

解题思路:一读题知道是拓扑排序,直接就拍了,后边一直WA。搜了一下原来输出队列的时候不是按照字典序来,晕死,对那一句话理解了半天都没想通,正向字典序遍历判断是满足条件的。后来举了特例,才知道是有问题的。看了一下可以后往前排列,每次排列最大的编号,这样再逆序输出就可以了。这个题主要就是这里了,要逆拓扑排序,还有就是数据量较大用矩阵存不下来,要用vector,不过还有一种邻接表的写法,后边再试试看了。详见code。

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=4857

code:

#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>using namespace std;const int MAXN = 30000+10;vector<int> map[MAXN];int indeg[MAXN],topo[MAXN];int T,n,m,u,v,cnt;struct cmp{  //比较函数,最大值优先    bool operator()(const int &a,const int &b){return a<b;}};void toposort(){    priority_queue<int,vector<int>,cmp> q;    for(int i=1;i<=n;i++) //将没有出度的点存入队列        if(indeg[i]==0)            q.push(i);    while(!q.empty()){        int x=q.top();        q.pop();        topo[++cnt]=x;  //逆序记录        for(int i=0;i<map[x].size();i++){            indeg[map[x][i]]--; //将关联关系--            if(indeg[map[x][i]]==0) //如果该点没有出度,放入队列                q.push(map[x][i]);        }    }}int main(){    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++) //初始化vector            map[i].clear();        memset(indeg,0,sizeof(indeg));        for(int i=1;i<=m;i++){            scanf("%d%d",&u,&v);            map[v].push_back(u); //反向存放,使值大的优先            indeg[u]++;        }        cnt=0;        toposort();        for(int i=cnt;i>1;i--) //方向输出            printf("%d ",topo[i]);        printf("%d\n",topo[1]);    }    return 0;}


0 0
原创粉丝点击