Problem 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
Author
SmallBeer(CML)
Source
题意:找到最强者,其实不用优先队列也可以.....简单拓扑排序,先判断度为零的点,因为要从小到大,所以直接循环即可.....
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <ctype.h> 7 #include <iomanip> 8 #include <queue> 9 #include <stdlib.h> 10 using namespace std; 11 12 #define M 550 13 14 int du[M],tp[M][M]; 15 int n,m,i,j; 16 17 void topu() 18 { 19 priority_queue<int,vector<int>,greater<int> > Q; //保证小值int先出队列 20 for(i=1;i<=n;i++){ 21 if(du[i]==0) 22 Q.push(i); 23 } 24 bool flag=0; 25 while(!Q.empty()){ 26 int ans=Q.top(); 27 Q.pop(); 28 if(!flag){ 29 printf("%d",ans); 30 flag=1; 31 } 32 else{ 33 printf(" %d",ans); 34 } 35 for(i=1;i<=n;i++){ 36 if(tp[ans][i]){ 37 du[i]--; 38 if(du[i]==0) 39 Q.push(i); 40 } 41 } 42 } 43 printf(" "); 44 } 45 46 int main() 47 { 48 int x,y; 49 while(~scanf("%d%d",&n,&m)){ 50 memset(du,0,sizeof(du)); 51 memset(tp,0,sizeof(tp)); 52 for(i=0;i<m;i++){ 53 scanf("%d%d",&x,&y); 54 if(!tp[x][y]){ 55 tp[x][y]=1; 56 du[y]++; 57 } 58 } 59 topu(); 60 } 61 }