Luogu P3243 [HNOI2015] cuisine making

Keywords: PHP

Portal

I read the solution of the problem

Given the order of point pairs, it is easy to think of topological ordering.

But if you sort by dictionary order, you will encounter smaller ones in front,

The counter examples can be cited: four dishes, limited to < 2,4 > < 3,1 >,

Then the least lexicographic order is 2,3,1,4, but the positive solution should be 3,1,2,4

Because sorting by dictionary order can only be arranged by the previous point, and the size of the next point cannot be known.

Through observation, it is found that to make the smallest appear as early as possible is to make the larger appear as late as possible.

The points that can be put at the back are certain.

Then connect the edges reversely, and finally output the reverse order of the topology.

Note that if the conditions are not met, apart from the fact that there is no entry point of 0 at the beginning, there may be some points to form a closed loop.

Therefore, it is necessary to determine whether the number of points in the discharge sequence is equal to the total number of points.

The code is as follows

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
#include<queue>
using namespace std;
const int maxn = 1e5+10;
int t,n,m,x,y,cnt,num;
int a[maxn],inn[maxn];
int head[maxn],to[maxn],nxt[maxn];

void add(int x,int y) {
    to[++cnt] = y;
    nxt[cnt] = head[x];
    head[x] = cnt;
}

void init() {
    cnt = num = 0;
    memset(head,0,sizeof(head));
    memset(to,0,sizeof(to));
    memset(nxt,0,sizeof(nxt));
    memset(inn,0,sizeof(inn));
}

void topo() {
    priority_queue <int> q;
    for(int i = 1; i <= n; i++)
        if(!inn[i]) q.push(i);
    if(q.empty()) {
        printf("Impossible!\n");
        return;
    }
    while(!q.empty()) {
        int u = q.top();
        q.pop();
        a[++num] = u;
        if(!head[u]) continue;
        for(int i = head[u]; i; i = nxt[i]) {
            int v = to[i];
            inn[v]--;
            if(inn[v] == 0) q.push(v);
        }
    }
    if(num < n) {
        printf("Impossible!\n");
        return;
    }
    for(int i = n; i >= 1; i--)
        printf("%d ",a[i]);
    printf("\n");
}

int main() {
    scanf("%d",&t);
    while(t--) {
        init();
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= m; i++) {
            scanf("%d%d",&x,&y);
            add(y,x);
            inn[x]++;
        }
        topo();
    }
    return 0;
}

Posted by Garion on Sun, 03 Nov 2019 12:30:32 -0800