糟糕的事情發生啦,現在大家都忙著逃命。但是逃命的通道很窄,大家只能排成一行。
現在有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 10
3 51 4
2 51 2
3 41 4
2 31 5
3 51 2
sample output
1 2 3 4 5糟糕的事情發生啦,現在大家都忙著逃命。但是逃命的通道很窄,大家只能排成一行。
現在有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 10
3 51 4
2 51 2
3 41 4
2 31 5
3 51 2
sample output
1 2 3 4 5
思路:明顯拓撲排序,但是要求序號最小的最先出,首先考慮一下正向建圖,發現有可能大的點會擋住小的點不能滿足最小的序號在前面
我們的目標是讓最小的點的編號盡量小
比如:1->2<-4 3
正向建圖每次讓最小的先出隊得到答案:1 4 2 3
正確答案 1 3 4 2
這並沒有讓2達到最小.
那麼需要反向建圖,相當於變成大的序號後出去,將所有能出去的點放入優先佇列,因為我們要讓前面最小的點盡量靠前,最小的點能不出隊就留下來,自然就保證了最小的點靠前
優先佇列會出去序號最大的點,那麼留下的就是序號最小的點,再反向輸出即可
#include
#define fi first
#define se second
#define for(a) for(int i=0;i#define sc(a) scanf("%d",&a)
#define show(a) cout<#define show2(a,b) cout<#define show3(a,b,c) couttypedef
long
long ll;
typedef pair<
int,
int> p;
typedef pairint> lp;
const ll inf =
1e17+10
;const
int n =
3e5+10;
const ll mod =
1000000007
;const
int base=
131;
mapint>ml;
int de[n]
,n,m,t,k,flag,top[n]
,cnt;
int co[n]
;vector<
int> v[n]
;priority_queue<
int> q;
void
bfs()}
while
(q.size()
)}}for
(int i=
1;i)printf
("%d "
,top[i]);
printf
("%d\n"
,top[n]);
}int
main()
for(
int i=
1;i<=m;i++
)bfs()
;}}
hdu 4857 逃生(優先佇列 逆拓撲排序)
題意是給你一些關係,來進行排序,前面的那個人一定在後乙個人前面,也在那些沒有交錢的人的前面。我們用逆拓撲排序,先把入度為零的數從大到小存入陣列。然後就是一般的拓撲排序。最後逆序輸出 include include include include include include includeusin...
HDU 4857 逃生 反向拓撲排序 優先佇列
hdu 4857 題意就是做乙個符合條件的排序,用到拓撲序列。我一開始wa了多發,才發現有幾個樣例過不了,發現1 2 3.的順序無法保證。後來就想用並查集強連,還是wa 後來發現髮用反向拓撲排序 優先佇列才可以通過 這裡注意把入度為0的入隊改成了出度為0的入隊 下面是ac include inclu...
HDU 4857 逃生(反向拓撲排序 優先佇列)
這題對序號輸出有要求,較小的序號優先輸出,所以用到優先佇列 優先佇列是優先彈出值最大的,所以最後要反向輸出結果,才是正確的output include include include include include include include include include using name...