题目序号配给--CSUSTOJ1033(字典序最小的拓扑排序)

题目链接https://csustacm.fun/problem/1033

Description

在一种竞赛中,题目往往是成套出现的。一道基础题,稍加改动就会使难度上升几个档次。

现在有n道题目,编号为1~n;给出了m个二元组,每个二元组表示 b题目是a题目的加强版,每个题目可能会有多个加强版,加强版的题目也可能会有加强版。

现在要将这n道题目放组成一场比赛,出于人文关怀方面的考虑,一道题目的简单版本必须放在其所有加强版的前面。

例如b是a的加强版,c是b的加强版 那么c在比赛中的题号必须大于a和b的题号,b的题号也必须大于a的题号

你需要做得,是输出一个长度为n的序列A,A[i] 表示编号为i的题目在比赛中的题号。

符合要求的答案很多,出题人并不想写spj,所以请输出字典序最小的方案。

Input

第一行为两个数n,m表示有n道题,m个二元组(n,m≤106)

接下来有m行,每行有两个数a,b 表示 题目b是题目a的加强版(1≤a,b≤n)。

输入保证有解

Output

按顺序输出每道题在比赛中的题号,要求字典序最小。


。。。这题也是签到题,仔细一看就差不多知道是拓扑排序了。那么我们对a必须在b前面这个条件当做引一条从a到b的有向边就可以跑拓扑排序了。注意最后输出的不是序列,而是1到n在序列中的位置。

以下是AC代码:

#include 
using namespace std;

const int mac=1e6+10;

int in[mac],id[mac];
vectorg[mac];
vectorans;

int main()
{
    int n,m;
    scanf ("%d%d",&n,&m);
    for (int i=1; i<=m; i++){
        int x,y;
        scanf ("%d%d",&x,&y);
        in[y]++;
        g[x].push_back(y);
    }
    priority_queue,greater >q;
    for (int i=1; i<=n; i++)
        if (in[i]==0)
            q.push(i);
    while(!q.empty()){
        int p=q.top();
        q.pop();
        ans.push_back(p);
        for (int i=0; i

 

你可能感兴趣的:(#,csust2017区域个人,#,拓扑排序)