• 安徽省2016“京胜杯”程序设计大赛_F_吃在工大


    吃在工大

    Time Limit: 1000 MS Memory Limit: 65536 KB
    Total Submissions: 51 Accepted: 15


    Description


         JH和他的好朋友YZ两名程序员回访母校合工大,准备在这住一段日子,都说“玩在安大,吃在工大”,JH又是一名典型吃货,于是决定在工大食堂好好吃一段日子,但是,面对美食诱惑:黄焖鸡、风暴干锅、麻辣香锅、奥尔良烤翅…由于时间有限,JH不知道哪顿饭吃哪个菜好。

    于是YZ为了帮助他解决这个问题,也顺便考考他,给他出了一个问题:“黄焖鸡必须在干锅花菜前面吃,干锅牛肉必须在干锅鱿鱼前面吃….你按这个要求下,就知道吃的顺序啦”。JH抓抓头,分分钟写了个程序搞定,现在,让你来写写看?输出一组JH符合条件下吃的食物的序列。

               假设JH每顿只吃一种食物,且每顿吃的都不同,食物编号1到N。




    Input


             先输入一个整数T,表示T(T<50)组数据。

    每组数据第一行输出一个整数,N,M,分别表示有N种食物,总共有M个约束条件,接下来M行每行输入两个正整数a,b(n>=a>0,n>=b>0),表示食物a必须在食物b之前吃。


    Output


             各组数据输出答案占一行,输出一组符合条件的序列(要求输出字典序最大的那一组),如果答案不存在,输出“-1”。


    Sample Input


    1
    4 3
    1 2 
    2 3
    4 3

    Sample Output


    4 1 2 3

    此题考得是拓扑排序,一开始做这道题的时候只知道是拓扑排序,当时带了几本书了都写的有,怪自己当初没有好好看书,不知道其中的原理,比赛时照着一个拓扑排序的程序写了,然后测试过了几次,都是正确的,还是不知道怎么改
    题解:拓扑排序就我理解就是在无环的图中(如果有环一定不能排),先找入度为0的点放入队列,但是找这个点也不是随便找,因为需要满足拓扑条件下时有多个是需要按字典序最大的情况,故我用到了优先队列,这样保证每次从其中取出时最大的,取出后,存入数组,并把取出的这个点所连接的点的入度-1,再次查找入度为0的点,进行此操作,直到队列空。详见程序
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <queue>
    
    using namespace std;
    
    const int maxn = 10000 + 5;
    vector<int> g[maxn];
    int du[maxn], n, m, L[maxn];
    
    bool toposort()
    {
    	memset(du, 0, sizeof(du));
    	for (int i=0; i<n; i++)
    		for (int j=0; j<g[i].size(); j++)
    			du[g[i][j]]++;
    	int tot = 0;
    	priority_queue<int> Q;
    	for (int i=0; i<n; i++)
    		if (!du[i]) Q.push(i);//入度为0的点存入优先队列
    	while (!Q.empty()) {
    		int x = Q.top(); Q.pop();
    		L[tot++] = x;//取出入度为0的点,并存入数组
    		for (int j=0; j<g[x].size(); j++){
    			int t = g[x][j];
    			du[t]--;//相连的点入度依次减一
    			if (!du[t])
    				Q.push(t);//把入度为0的点放入优先队列
    		}
    	}
    	if (tot == n)
    		return 1;
    	return 0;
    }
    
    int main(int argc, char const *argv[])
    {
    	int t;
    	scanf("%d", &t);
    	while (t--)
    	{
    		scanf("%d%d", &n, &m);
    		for(int i=0;i<n;i++)
                g[i].clear();
    		while (m--)
    		{
    			int N, M;
    			scanf("%d%d", &N, &M);
    			g[N-1].push_back(M-1);
    		}
    		int first = 0;
    		if (toposort()) {
                for (int i=0; i<n; i++) {
                    if (first)
                        printf(" ");
                    first = 1;
                    printf("%d", L[i]+1);
                }
                printf("
    ");
            }
            else
                printf("-1
    ");
    	}
    	return 0;
    }



  • 相关阅读:
    POJ1028 Web Navigation【堆栈+模拟】
    UVa10276 HDU1329 ZOJ1239 Hanoi Tower Troubles Again!【递推函数+打表】
    UVALive5369 UVa732 HDU1515 ZOJ1004 Anagrams by Stack【DFS+堆栈】
    HDU5776 sum【前缀和+模除】
    POJ1844 Sum【水题+数学题】
    AOJ0558 Cheese【BFS】
    POJ3009 Curling 2.0【DFS】
    HDU1163 Eddy's digital Roots(解法二)【快速模幂+九余数定理】
    HDU1210 Eddy's 洗牌问题【递推函数+模拟】
    Vijos P1571 笨笨的导弹攻击【最长上升子序列+DP】
  • 原文地址:https://www.cnblogs.com/fayne/p/7224799.html
Copyright © 2020-2023  润新知