AcWing 3704:排队——拓扑排序+优先队列+邻接表

【题目来源】
https://www.acwing.com/problem/content/3707

【题目描述】
N 个小朋友,编号 1∼N,要排成一队。
在安排每个人的顺序时,有 M 个要求,每个要求包含两个整数 a,b,表示小朋友 a 要排在小朋友 b 的前面。
请你找出符合所有要求的排队顺序。

【输入格式】
第一行包含整数 N,M。
接下来 M 行,每行包含两个整数 a,b。

【输出格式】
按排好队列从前到后的顺序在一行内输出每个小朋友的编号。
保证至少存在一个符合条件的顺序。
当符合条件的排队顺序不唯一时,编号更小的小朋友尽量更靠前。

【数据范围】
1≤N≤500,
1≤M≤5000,
1≤a,b≤N,
保证数对 (a,b) 各不相同。

【输入样例】
4 3
1 2
2 3
4 3

【输出样例】
1 2 4 3

【算法分析】
● 当符合条件的排队顺序不唯一时,编号更小的小朋友尽量更靠前 → 优先队列
● 拓扑排序算法步骤:
(1)从有向图中选择一个无前驱(即入度为0)的顶点并且输出它。
(2)从图中删除该顶点及所有以它为尾的有向边。
(3)重复上述两步,直至不存在无前驱的顶点。
(4)若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在环,否则输出的顶点序列就是一个拓扑序列。

代码如下:

【代码】

#include 
using namespace std;
 
const int maxn=505;
int ind[maxn];
vector g[maxn];
vector path;
int n,m;
 
void topSort() {
    priority_queue, greater> q;
    for(int i=1; i<=n; i++) {
        if(!ind[i]) q.push(i);
    }
 
    while(!q.empty()) {
        int t=q.top();
        q.pop();
        path.push_back(t);
        for(int i=0; i>n>>m;
    while(m--) {
        int x,y;
        cin>>x>>y;
        g[x].push_back(y);
        ind[y]++;
    }
 
    topSort();
    for(auto x:path) {
        cout<

你可能感兴趣的:(信息学奥赛,队列,拓扑排序+邻接表,算法)