有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
杭电ACM集训队训练赛(VII)
因为题目要求是当存在多个情况时,按照小的来进行排序,所以就要对入度为0的点一个个进行入队操作了,同时不断的更新点的入度。 题目的坑点就在于,要考虑重边。典型的拓扑排序题目,我的第一个拓扑排序题,感觉代码要改进,不然太麻烦了。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int main()
{
int n,i,j,k,m,p1,p2,indegree[1000],v[1000],num;
int map[505][505];
queue<int>qu;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(map,0,sizeof(map));
memset(indegree,0,sizeof(indegree));
for(i=1;i<=m;i++)
{
scanf("%d%d",&p1,&p2);
if(!map[p1][p2]) //这里判断重边,如果没有就wa了
indegree[p2]++;
map[p1][p2]=1;
}
for(i=1;i<=n;i++)
if(!indegree[i]){qu.push(i);indegree[i]--; break;} //先找第一个入度为0的点,一旦找到就break掉。
num=0;
while(!qu.empty())
{
v[num]=qu.front();qu.pop();num++;
for(i=1;i<=n;i++)
{
if(map[v[num-1]][i])
indegree[i]--;
}
for(i=1;i<=n;i++)
if(!indegree[i]){
qu.push(i);indegree[i]--;break; //同上,一旦找到,就马上跳出
}
}
for(i=0;i<num-1;i++)
printf("%d ",v[i]);
printf("%d\n",v[num-1]);
}
return 0;
}