description
有n個比賽隊(1<=n<=500),編號依次為1,2,3,……,n進行比賽,比賽結束後,裁判委員會要將所有參賽隊伍從前往後依次排名,但現在裁判委員會不能直接獲得每個隊的比賽成績,只知道每場比賽的結果,即p1贏p2,用p1,p2表示,排名時p1在p2之前。現在請你程式設計序確定排名。
input
輸入有若干組,每組中的第一行為二個數n(1<=n<=500),m;其中n表示隊伍的個數,m表示接著有m行的輸入資料。接下來的m行資料中,每行也有兩個整數p1,p2表示即p1隊贏了p2隊。
output
給出乙個符合要求的排名。輸出時隊伍號之間有空格,最後一名後面沒有空格。
其他說明:符合條件的排名可能不是唯一的,此時要求輸出時編號小的隊伍在前;輸入資料保證是正確的,即輸入資料確保一定能有乙個符合要求的排名。
sample input
4 3sample output1 22 3
4 3
1 2 4 3參考程式
def
out(ls)
:for i in
range
(len
(ls)-1
):print
(ls[i]
, end=
" ")
print
(ls[-1
])while
true
:try
: n, m =
map(
int,
input()
.split())
pre_dic =
next_dic =
for i in
range(1
, n +1)
: pre_dic[i]=[
] next_dic[i]=[
]for i in
range
(m):
a, b =
map(
int,
input()
.split())
pre_dic[b]
next_dic[a]
res =
while
true
: firstnodelist =
for i in
range(1
, n +1)
:# 查詢沒有前驅結點的結點集合
if i in pre_dic.keys(
)and
len(pre_dic[i])==
0:node =
min(firstnodelist)
# 找出序號最小的結點node
for n in next_dic[node]
:# n是node的各後繼結點
pre_dic[n]
.remove(node)
m -=
1 pre_dic.pop(node)
res = res +
[node]
if m ==0:
# 所有邊都已經去掉
break
tail =
list
(pre_dic.keys())
# 所有的邊去掉後,圖中剩餘的最後幾個沒有前驅的結點
tail.sort(
) res += tail
out(res)
except
:break
思路分析:
本題的題意是根據每行輸入的部分次序關係,從而還原整個比賽程式的次序關係。刻畫問題時,可以將隊編號用結點表示,對之間的次序關係用有向邊表示,那麼每行輸入的p1,p2表示p1隊贏了p2隊,就可以表示為p1→p2。這樣m行的輸入資料實際上就是給出的m條有向邊。這樣問題的全域性表示就刻畫出來了,實際上是一張有向無環圖。接下來確定全域性次序關係的思路是,每一步掃瞄所有沒有前驅結點的結點,這些結點是「候選第1名」,從中選取序號最小的,計入結果列表,它就是全域性第1名,然後將此結點從圖中刪除,並把該結點發出的所有邊刪除。重複此過程直至所有邊刪除完畢,最後剩餘的結點再按照標號從小到大排序,併入到結果列表中
實現方法:
HDU 1285 確定比賽名次(拓撲排序演算法)
題目大意 有n個比賽隊 1 n 500 編號依次為1,2,3,n進行比賽,比賽結束後,裁判委員會要將所有參賽隊伍從前往後依次排名,但現在裁判委員會不能直接獲得每個隊的比賽成績,只知道每場比賽的結果,即p1贏p2,用p1,p2表示,排名時p1在p2之前。現在請你程式設計序確定排名。拓撲排序 是指由某個...
資料結構與演算法 演算法 演算法和資料結構
資料結構與演算法 演算法 好吧,在這裡,您被優秀或優秀的軟體開發人員所隔開。在這種情況下,我會告訴您一開始或至少在我的情況下,並且我知道大多數時候,對於我認識的大多數人,您會覺得自己是乙個無能的人或白痴。基本上,我怎麼可能不理解這一點,然後您會感到沮喪。在這種情況下,我會告訴您情況並不像您想的那麼糟...
資料結構 資料結構與演算法01
1 求一組整數中的最大值。演算法 基本操作是 比較兩個數的大小 模型 仔細想想 你並不知道這個整數到底是多大?整數過大你該怎麼去表示?2 足協的資料庫管理的程式 演算法 需要管理的專案?如何管理?使用者介面?模型 3 資料與資料結構 資料 所有能被輸入到計算機中,並被計算機處理的符號的集合計算機操作...