zoukankan      html  css  js  c++  java
  • 【杭电】[4857]逃生

    逃生

    Problem Description
    糟糕的事情发生啦,现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。

    现在有n个人,从1标号到n。同时有一些奇怪的约束条件,每个都形如:a必须在b之前。
    同时,社会是不平等的,这些人有的穷有的富。1号最富,2号第二富,以此类推。有钱人就贿赂负责人,所以他们有一些好处。

    负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推。

    那么你就要安排大家的顺序。我们保证一定有解。 

    Input
    第一行一个整数T(1 <= T <= 5),表示测试数据的个数。
    然后对于每个测试数据,第一行有两个整数n(1 <= n <= 30000)和m(1 <= m <= 100000),分别表示人数和约束的个数。

    然后m行,每行两个整数a和b,表示有一个约束a号必须在b号之前。a和b必然不同。
     
    Output
    对每个测试数据,输出一行排队的顺序,用空格隔开。
     
    Sample Input
    1 5 10 3 5 1 4 2 5 1 2 3 4 1 4 2 3 1 5 3 5 1 2
     
    Sample Output
    1 2 3 4 5

    明显的拓扑排序,但是这一题的条件有两个,除了给的限定条件外还应该优先按照从1~n输出。

    所以考虑使用优先队列来取合适的点

    考虑前面的应该尽量比后面的大,所以若用优先队列,则若正向建边,会导致队列中已有的上一层元素比后推入的元素大,从而使队列完全按照从大到小输出,产生错误结果。

    所以考虑反向建边,则先取最一小级中最大的,并且每一次取当前队列中的最大的,则可以保证在按照1~n的顺序的情况下,按照特殊条件排序。

    因为是反向建边,所以要把得到的结果倒序输出。

    测试数据:

    10
    6 4
    6 3
    3 1
    5 4
    4 2

    输出:

    6 3 1 5 4 2


    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int n;
    int cnt[30200];
    int topo[30200];
    struct node {
    	int next;
    	int to;
    } a[100200];
    int head[30200];
    void toposort() {
    	priority_queue<int>q;
    	for(int i=1; i<=n; i++)
    		if(!cnt[i]) {
    			q.push(i);
    		}
    	int t=0;
    	while(!q.empty()) {
    		int ttop=q.top();
    		q.pop();
    		topo[t++]=ttop;
    		for(int i=head[ttop]; i!=-1; i=a[i].next) {
    			cnt[a[i].to]--;
    			if(!cnt[a[i].to])
    				q.push(a[i].to);
    		}
    	}
    }
    int main() {
    	int T;
    	scanf("%d",&T);
    	while(T--) {
    		int m;
    		scanf("%d %d",&n,&m);
    		memset(cnt,0,sizeof(cnt));
    		memset(head,-1,sizeof(head));
    		for(int i=0; i<m; i++) {
    			int u,v;
    			scanf("%d %d",&u,&v);
    			a[i].to=u;
    			a[i].next=head[v];
    			head[v]=i;
    			cnt[u]++;
    		}
    		toposort();
    		for(int i=n-1; i>=0; i--)
    			printf("%d%c",topo[i],i==0?'
    ':' ');
    	}
    	return 0;
    }


    题目地址:【杭电】[4857]逃生

  • 相关阅读:
    [HNOI2014]江南乐
    烦人的数学作业(数位dp)
    http2.0请求springboot接口
    01背包动态规划
    坑点总结
    [机房测试] 堆石子
    [机房测试] 出租车
    [机房测试] 下棋
    [机房测试] number
    [CSP-S2019] 树的重心
  • 原文地址:https://www.cnblogs.com/BoilTask/p/12569422.html
Copyright © 2011-2022 走看看