標籤:des style blog java color strong
逃生Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 74 Accepted Submission(s): 13
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
15 103 51 42 51 23 41 42 31 53 51 2
Sample Output
1 2 3 4 5
AuthorCLJ
思路:注意此題不是保證字典序,而是要最小的盡量在前面。反向建圖,將大的優先順序放前面,然後逆序輸出。首先反向建圖+逆序輸出為一個答案。
然後要保證最小的在最前面,因為是逆序輸出,所以優先順序要反過來。
代碼:
#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <queue>#define maxn 30005using namespace std;int n,m,ans;bool vis[maxn];int in[maxn];vector<int>edge[maxn];int main(){ int i,j,t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(in,0,sizeof(in)); for(i=1;i<=n;i++) edge[i].clear(); int u,v; for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); in[u]++; edge[v].push_back(u); } priority_queue<int> q; for(i=1;i<=n;i++) { if(in[i]==0) q.push(i); } memset(vis,0,sizeof(vis)); vector<int>res; ans=0; while(!q.empty()) { ans++; u=q.top(); res.push_back(u); q.pop(); vis[u]=1; for(i=0;i<edge[u].size();i++) { v=edge[u][i]; in[v]--; if(in[v]==0) q.push(v); } } for(i=res.size()-1;i>=0;i--) { if(i==res.size()-1) printf("%d",res[i]); else printf(" %d",res[i]); } puts(""); } return 0;}/*204 34 14 23 2*/