hdu4857
逃生
Time Limit: 2000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6733????Accepted Submission(s): 1967
Problem Description 糟糕的事情發(fā)生啦,現(xiàn)在大家都忙著逃命。但是逃命的通道很窄,大家只能排成一行。
現(xiàn)在有n個人,從1標(biāo)號到n。同時有一些奇怪的約束條件,每個都形如:a必須在b之前。
同時,社會是不平等的,這些人有的窮有的富。1號最富,2號第二富,以此類推。有錢人就賄賂負(fù)責(zé)人,所以他們有一些好處。
負(fù)責(zé)人現(xiàn)在可以安排大家排隊的順序,由于收了好處,所以他要讓1號盡量靠前,如果此時還有多種情況,就再讓2號盡量靠前,如果還有多種情況,就讓3號盡量靠前,以此類推。
那么你就要安排大家的順序。我們保證一定有解。
Input 第一行一個整數(shù)T(1 <= T <= 5),表示測試數(shù)據(jù)的個數(shù)。
然后對于每個測試數(shù)據(jù),第一行有兩個整數(shù)n(1 <= n <= 30000)和m(1 <= m <= 100000),分別表示人數(shù)和約束的個數(shù)。
然后m行,每行兩個整數(shù)a和b,表示有一個約束a號必須在b號之前。a和b必然不同。
Output 對每個測試數(shù)據(jù),輸出一行排隊的順序,用空格隔開。
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
解題報告:有n個點,有m個條件限制,限制是像這樣的,輸入a ?b,表示a必須排在b的前面,如果不能確定兩個數(shù)誰排在前面則盡量把小的排在前面。
首先把出度為0的點加入到優(yōu)先隊列中,然后每次用優(yōu)先隊列中彈出的點去更新其它點的出度,更新的同時如果又有其它點的出度為0的話又加到優(yōu)先隊列中,
最后按照從優(yōu)先隊列中出隊的反序輸出就可以了。
#include<bits/stdc++.h> using namespace std; const int maxn=30000+10; int n,m,a,b; vector<int> v[maxn]; int in[maxn],vis[maxn]; int main() {int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i=1; i<=n; i++){v[i].clear();in[i]=0;}for(int i=0; i<m; i++){scanf("%d%d",&a,&b);v[b].push_back(a);in[a]++;}priority_queue<int> q;vector<int>vi;for(int i=1; i<=n; i++){if(in[i]==0){q.push(i);//vis[i]=1;}}while(!q.empty()){int k=q.top();q.pop();vi.push_back(k);for(int i=0; i<v[k].size(); i++){int x=v[k][i];in[x]--;if(in[x]==0)q.push(x);}}for(int i=vi.size()-1; i>0; i--)printf("%d ",vi[i]);printf("%d\n",vi[0]);}return 0; }總結(jié)
- 上一篇: zcmu-2159
- 下一篇: SpringCloud 入门教程(一):