zoukankan      html  css  js  c++  java
  • 安徽省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;
    }



  • 相关阅读:
    1442. Count Triplets That Can Form Two Arrays of Equal XOR
    1441. Build an Array With Stack Operations
    312. Burst Balloons
    367. Valid Perfect Square
    307. Range Sum Query
    1232. Check If It Is a Straight Line
    993. Cousins in Binary Tree
    1436. Destination City
    476. Number Complement
    383. Ransom Note
  • 原文地址:https://www.cnblogs.com/fayne/p/7224799.html
Copyright © 2011-2022 走看看