确定比赛名次(拓扑排序基本例题)

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();///开始拓扑
    }
}

 

 
 
posted @ 2018-06-03 16:40  王陸  阅读(921)  评论(0编辑  收藏  举报