hdu 1285 确定比赛名次(拓扑排序)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 1285 确定比赛名次(拓扑排序)相关的知识,希望对你有一定的参考价值。

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

思路:a队赢了b队,代表一个从a到b的有向边,对这个图求拓扑排序,如果有多个答案,按照数字升序输出。寻找拓扑序列,看代码注释。

 

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
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 600;
int mp[N][N];
int edge[N];
int flag[N];
struct line
{
    int exist;   //代表当前边是否存在
    int u;       //边的起始点
    int v;       //边的终点
};
struct line l[N * N];

void debug(int *num, int n)
{
    for (int i = 1; i <= n; i++)
        printf("%d%c", num[i], i == n ? \n :  );
}

int main()
{
    int n, m;
    while (scanf("%d%d", &n, &m) != EOF)        //n代表点的数目,m代表边的数目。
    {
        for (int i = 0; i < m; i++)             //边的输入
        {
            scanf("%d%d", &l[i].u, &l[i].v);
            l[i].exist = 1;
        }
        for (int i = 0; i < n; i++)             //循环n次寻找拓扑序列
        {
            for (int j = 1; j <= n; j++)        //flag[i]代表第i个点是否为入度为0的点
                flag[j] = 1;
            for (int j = 0; j < m; j++)         //如果有边的终点是j,那么flag[j]置零。
            {
                if(l[j].exist == 1)
                    flag[l[j].v] = 0;
            }
            for (int j = 0; j < i; j++)         //已经加入拓扑序列的点也置零。
                flag[edge[j]] = 0;
            //debug(flag, n);
            for (int j = 1; j <= n; j++)        //从终点里选取一个数字最小的点。
            {
                if (flag[j] == 1)
                {
                    edge[i] = j;
                    break;
                }
            }
            for (int j = 0; j < m; j++)         //对于加入拓扑序列的这个点,删除其所在的边。
            {
                if(l[j].u == edge[i])
                    l[j].exist = 0;
            }
        }
        for (int i = 0; i < n; i++)             //拓扑序列已找到,输出即可。
            printf("%d%c", edge[i], i == n - 1 ? \n :  );
    }
    return 0;
}

 

 

以上是关于hdu 1285 确定比赛名次(拓扑排序)的主要内容,如果未能解决你的问题,请参考以下文章

HDU-1285 确定比赛名次(拓扑排序)

HDU 1285 确定比赛名次(拓扑排序+优先队列)

[ACM] hdu 1285 确定比赛名次 (拓扑排序)

HDU 1285 确定比赛名次(拓扑排序模板)

HDU-1285-确定比赛名次(拓扑排序)

HDU 1285 确定比赛名次(拓扑排序基础题)