安徽省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("\n");
        }
        else
            printf("-1\n");
	}
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章