4010: [HNOI2015]菜肴制作

拓扑排序+堆。

F8S_55}3{I3EG_2[8XG0B~7 转自popoqqq神犇。

反向建图跑拓扑排序然后逆序输出。

为什么不能正的来呢,因为不知道选当前菜要先制作哪种菜。

逆序过来跑拓扑的话,也能保证满足限制条件编号小的在前面。

题外话:我都打完了才发现第三个样例输出不对,一看题直接就弃疗了。。事实证明就改动几个字母。。。。

toposort我一直喜欢叫”土拨”sort,可能是因为我口语不好吧。。。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 100000 + 10;
const int maxm = 200000 + 10;
priority_queue<int> q;
int res[maxn],cnt;
int g[maxn],v[maxm],next[maxm],in[maxn],eid;
int T,n,m,u;

void addedge(int a,int b) {
    v[eid]=b; next[eid]=g[a]; g[a]=eid++; in[b]++;
}

int main() {
    scanf("%d",&T);
    while(T--) {
        memset(g,-1,sizeof(g)); eid=0;
        scanf("%d%d",&n,&m);
        cnt=0;
        for(int i=1,a,b;i<=m;i++) {
            scanf("%d%d",&a,&b);
            addedge(b,a);            
        }
        for(int i=1;i<=n;i++) if(!in[i]) q.push(i);
        while(!q.empty()) {
            u=q.top(); q.pop();    
            for(int i=g[u];~i;i=next[i]) {
                in[v[i]]--;
                if(!in[v[i]]) q.push(v[i]);
            }
            res[++cnt]=u;
        }
        if(cnt<n) printf("Impossible!\n");
        else {
            for(int i=n;i>=1;i--) printf("%d ",res[i]);
            printf("\n");
        }
    }
    return 0;    
}
posted @ 2016-06-27 17:08  invoid  阅读(149)  评论(0编辑  收藏  举报