1. 程式人生 > >確定比賽名次(拓撲排序基本例題)

確定比賽名次(拓撲排序基本例題)

!= 節點 text ring spl RM TP tran ret



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 3 1 2 2 3 4 3

Sample Output

1 2 4 3
#include<stdio.h>
#include<string.h>
int
mp[510][510]; int n,indegree[510]; void toposort() { int i,j,top,k=0; for(i=0;i<n;i++)///遍歷這個鄰接矩陣 { for(j=1;j<=n;j++) { if(indegree[j]==0)///找到入度為0的節點 { top=j; break; } } if(i==n-1
) { printf("%d\n",top); } else { printf("%d ",top); } indegree[top]--;///將該節點的入度更新為-1,避免重復入隊 for(j=1;j<=n;j++)///刪除與該點關聯的邊(即與該點相連的點的入度減一) { if(mp[top][j]) { indegree[j]--; } } } } int main() { int i,a,b,m; while(scanf("%d%d",&n,&m)!=EOF) { memset(indegree,0,sizeof(indegree));///初始化為0 memset(mp,0,sizeof(mp)); for(i=0;i<m;i++) { scanf("%d%d",&a,&b); if(mp[a][b]==0) { mp[a][b]=1;///兩隊開始建立聯系 indegree[b]++;///前者戰勝後者,後者的入度加一 } } toposort();///開始拓撲 } }

確定比賽名次(拓撲排序基本例題)