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

HDU 1285 確定比賽名次(拓撲排序基礎題)

個數 排名 有向無環圖 沒有 left php 輸出 編號 整數

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1285

題目:

有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 題解:拓撲排序的模板題。拓撲排序看代碼就很好理解了。 拓撲排序原理:

1.從DAG(有向無環圖)中選一個 沒有前驅(即入度為0)的頂點並輸出。
2.從圖中刪除該頂點和所有以它為起點的有向邊。
3.重復1和2直到當前的DAG為空或當前圖中不存在無前驅的頂點為止,後一種情況說明有向圖中一定有環。

代碼:
 1
#include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int N=555; 8 int n,m; 9 int in[N]; 10 bool E[N][N]; 11 queue <int> Q; 12 13 void toposort(){ 14 for(int i=1;i<=n;i++){ 15 //
尋找入度為0的點 16 int j=1; 17 while(in[j]!=0) j++; 18 in[j]--; 19 Q.push(j); 20 //將關聯的點的入度減1,即刪除與該節點關聯的邊 21 for(int k=1;k<=n;k++){ 22 if(E[j][k]) in[k]--; 23 } 24 } 25 } 26 27 int main(){ 28 int a,b; 29 while(scanf("%d%d",&n,&m)!=EOF){ 30 memset(E,0,sizeof(E)); 31 memset(in,0,sizeof(in)); 32 for(int i=1;i<=m;i++){ 33 scanf("%d%d",&a,&b); 34 if(!E[a][b]){ 35 E[a][b]=1; 36 in[b]++; 37 } 38 } 39 toposort(); 40 while(!Q.empty()){ 41 if(Q.size()==1) printf("%d\n",Q.front()); 42 else printf("%d ",Q.front()); 43 Q.pop(); 44 } 45 } 46 47 return 0; 48 }

HDU 1285 確定比賽名次(拓撲排序基礎題)