欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hdu4857逃生——拓扑排序

程序员文章站 2024-03-19 11:51:04
...

题目链接
题意
n个人要出逃,m个约束条件,a b表示a这个人必须在b这个人之前出去,同时序号小的人尽量前面出去。求符合要求的一个顺序。
思路
拓扑排序:将有向无环图G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。这里写一个拓扑排序还不够,因为题目还要求序号小的人排在前面,单纯用一个优先队列是得不到正确答案的,因此采用建反图的思路然后把答案逆序输出。
代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
vector<int>tu[30010],ans;
priority_queue<int>q;
int in[30010];//各点的入度
int T,n,m;
int main()
{
    int a,c,i,j,tp;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        memset(in,0,sizeof(in));//初始化
    	ans.clear();
    	for(i=0;i<=n;i++){
    		tu[i].clear();
		}
		while(!q.empty()) q.pop();
        while(m--)
        {
            scanf("%d%d",&a,&c);
            tu[c].push_back(a);
            in[a]++;
        }
        int i,j;
	    for(i=1;i<=n;i++)
	        if(in[i]==0) q.push(i);
	    while(!q.empty()){
            tp=q.top();
            q.pop();
            ans.push_back(tp);
            //printf("ans[%d]=%d\n",count-1,ans[count-1]);
            for(i=0;i<tu[tp].size();i++){
                in[tu[tp][i]]--;
                if(in[tu[tp][i]]==0){
                    q.push(tu[tp][i]);
                }
            }
        }
	    for(i=ans.size()-1;i>0;i--){
            printf("%d ",ans[i]);
        }
        printf("%d\n",ans[0]);
    }
    return 0;
}
相关标签: 拓扑排序