题目序号配给 字典序最小的拓扑排序

来源:长沙理工大学2018区域赛个人选拔赛1

题目:

描述:
在一种竞赛中,题目往往是成套出现的。一道基础题,稍加改动就会使难度上升几个档次。
现在有n道题目,编号为1~n;给出了m个二元组,每个二元组 <a,b> < a , b > 表示 b题目是a题目的加强版,每个题目可能会有多个加强版,加强版的题目也可能会有加强版。
现在要将这n道题目放组成一场比赛,出于人文关怀方面的考虑,一道题目的简单版本必须放在其所有加强版的前面。
例如ba的加强版,cb的加强版 那么c在比赛中的题号必须大于ab的题号,b的题号也必须大于a的题号
你需要做得,是输出一个长度为n的序列AA[i] 表示编号为i的题目在比赛中的题号。
符合要求的答案很多,出题人并不想写spj,所以请输出字典序最小的方案。

输入:
第一行为两个数n,m表示有n道题,m个二元组(n,m≤106n,m \leq 10^6n,m≤106)
接下来有m行,每行有两个数a,b 表示 题目b是题目a的加强版(1≤a,b≤n1 \leq a,b \leq n1≤a,b≤n)。
输入保证有解

输出:
按顺序输出每道题在比赛中的题号,要求字典序最小。
样例输入:
5 10
5 2
4 1
2 1
3 4
2 4
3 2
5 4
3 5
3 1
5 1
样例输出:
5 3 1 4 2

题解:

套一个字典序最小的拓扑排序模板就好了

AC代码:

#include 
#define debug(x) cout<<#x<<" = "<
#define INF 0x3f3f3f3f
using namespace std;
/********************拓扑排序+队列实现****************************/
const int maxv = 1e6 + 10;
const int maxe = 1e6 + 10;
struct Edge {
    int to, val, next;
} edge[maxe];
int head[maxe], in[maxe], cnt, TPOindex, TPOQueue[maxv], ans[maxv];
int n, m;
priority_queue<int, vector<int>, greater<int> > pqi;
void Topsort() {
    for (int i = 1 ; i <= n ; i++) {
        if (in[i] == 0) {
            pqi.push(i);
        }
    }
    while (!pqi.empty()) {
        int cur = pqi.top();
        pqi.pop();
        TPOQueue[TPOindex++] = cur;
        for (int i = head[cur]; i != -1; i = edge[i].next) {
            in[edge[i].to]--;
            if (in[edge[i].to] == 0)
                pqi.push(edge[i].to);
        }
    }
}
void addedge(int from, int to) {
    TPOindex = 0;
    edge[cnt].to = to;
    edge[cnt].next = head[from];
    head[from] = cnt++;
}
void init() {
    cnt = 0;
    memset(head, -1, sizeof head);
    memset(in, 0, sizeof in);
}
/********************拓扑排序+队列实现****************************/
int main(void) {
    init();
    int  t1, t2;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &t1, &t2);
        addedge(t1, t2);
        in[t2]++;
    }
    Topsort();

    int index = 1;
    for (int i = 0; i < TPOindex; i++)
        ans[TPOQueue[i]] = index++;
    for (int i = 1; i <= n; i++)
        printf("%d%c", ans[i], i == n ? '\n' : ' ');
    return 0;
}

你可能感兴趣的:(图论)