Problem Description 糟糕的事情發生啦,如今你們都忙着逃命。可是逃命的通道很窄,你們只能排成一行。php
如今有n我的,從1標號到n。同時有一些奇怪的約束條件,每一個都形如:a必須在b以前。
同時,社會是不平等的,這些人有的窮有的富。1號最富,2號第二富,以此類推。有錢人就賄賂負責人,因此他們有一些好處。ios負責人如今能夠安排你們排隊的順序,因爲收了好處,因此他要讓1號儘可能靠前,若是此時還有多種狀況,就再讓2號儘可能靠前,若是還有多種狀況,就讓3號儘可能靠前,以此類推。測試
那麼你就要安排你們的順序。咱們保證必定有解。spa
Input 第一行一個整數T(1 <= T <= 5),表示測試數據的個數。 而後對於每一個測試數據,第一行有兩個整數n(1 <= n <=
30000)和m(1 <= m <= 100000),分別表示人數和約束的個數。code而後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
We have carefully selected several similar problems for you: 6742
6741 6740 6739 6738ip
注意:這裏的排序依照的規則必定不是 「字典序」 排序的規則
。#include<iostream> #include<cstdio> #include<queue> #include<vector> using namespace std; const int Len = 30005; vector<int> edge[Len], ans; int n, m; int in[Len]; //表示圖中度某個點的入度 void Solve() { priority_queue<int> q; //優先級隊列,權值大的會被放在前面 for(int i = 1; i <= n; i ++) if(! in[i]) q.push(i); int u, v; while(! q.empty()) { u = q.top(); q.pop(); ans.push_back(u); //減小與u相連的點v的入度 for(int i = 0; i < edge[u].size(); i ++) { v = edge[u][i]; if(-- in[v] == 0) { q.push(v); } } } for(int i = ans.size() - 1; i >= 0; i --) if(i) printf("%d ", ans[i]); else printf("%d", ans[i]); printf("\n"); } void init() { for(int i = 0; i <= n; i ++) { edge[i].clear(); in[i] = 0; } ans.clear(); } int main() { /* freopen("A.txt","r",stdin); */ /* freopen("Ans.txt","w",stdout); */ int t; scanf("%d", &t); while(t --) { scanf("%d %d", &n, &m); init(); int u, v; for(int i = 1; i <= m; i ++) { scanf("%d %d", &u, &v); edge[v].push_back(u); in[u] ++; } Solve(); } return 0; }