P3243 [HNOI2015]菜肴制作(拓扑排序)

P3243 [HNOI2015]菜肴制作

题目误导你正着做拓扑排序,然鹅你可以手造数据推翻它。于是就只能倒着做

我们开个优先队列,每次把可填的最大的编号取出来搞,最后倒着输出拓扑序就好辣

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 100005
int n, m, tp, Q[N], in[N];
int cnt,hd[N],nxt[N<<1],ed[N],poi[N<<1];
inline void add(int x,int y){
    nxt[ed[x]]=++cnt, hd[x]=hd[x]?hd[x]:cnt,
    ed[x]=cnt, poi[cnt]=y, ++in[y];
}
void bfs() {
    priority_queue<int> h; 
    for (int i = 1; i <= n; ++i)
        if (!in[i]) h.push(i);
    while (!h.empty()) {
        int x = h.top(); h.pop();
        Q[++tp] = x;
        for(int i=hd[x];i;i=nxt[i]){
            --in[poi[i]];
            if(in[poi[i]]==0) h.push(poi[i]);
        }
    }
}
int main() {
    int T; scanf("%d",&T);
    while(T--){
        memset(in,0,sizeof(in));
        memset(hd,0,sizeof(hd));
        memset(ed,0,sizeof(ed));
        memset(nxt,0,sizeof(nxt)); tp=cnt=0;
        scanf("%d%d", &n, &m);
        for (int i = 1, f, t; i <= m; ++i) 
            scanf("%d%d", &f, &t),add(t,f);
        bfs();
        if (tp < n) {puts("Impossible!");continue;}
        for (int i = n;i; --i) printf("%d ", Q[i]);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/kafuuchino/p/10660742.html
今日推荐