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

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

拓扑序就是求一个序列 数 a 出现在数 b 前面,最终输出满足条件的序列即可;

过程就是每次选取入度为0的数每次把它计入拓扑序列,并把与该点相连的所有边删除即可;

由于拓扑序不是唯一的本题要求序号小的放前面,所以可以用优先队列;

#include <math.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <queue>
#define met(a, b) memset(a, b, sizeof(a))
using namespace std;
#define N 510

struct node
{
    int x;
    bool friend operator < (node a, node b)
    {
        return a.x > b.x;///小的先出来;
    }
};

int G[N][N], du[N], n, m, u, v, ans[N];

void topo()
{
    priority_queue<node>Q;
    node p, q;
    for(int i=1; i<=n; i++)
    {
        if(du[i]==0)
            p.x=i,
            Q.push(p);
    }
    int k=1;
    while(Q.size())
    {
        p=Q.top();Q.pop();
        ans[k++] = p.x;

        for(int i=1; i<=n; i++)
        {
            if(G[p.x][i])
            {
                du[i]--;
                if(du[i]==0)
                    q.x=i,Q.push(q);
            }
        }
    }
}


int main()
{
    while(scanf("%d %d", &n, &m)!=EOF)
    {
        met(G,0);met(ans, 0);
        for(int i=1; i<=m; i++)
        {
            scanf("%d %d", &u, &v);
            if(G[u][v]==0)
            {
                G[u][v] = 1;
                du[v]++;
            }
        }
        topo();

        for(int i=1; i<=n; i++)
            printf("%d%c", ans[i], i==n?'
':' ');
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5026331.html