4010: [HNOI2015]菜肴制作
拓扑排序+堆。
反向建图跑拓扑排序然后逆序输出。
为什么不能正的来呢,因为不知道选当前菜要先制作哪种菜。
逆序过来跑拓扑的话,也能保证满足限制条件编号小的在前面。
题外话:我都打完了才发现第三个样例输出不对,一看题直接就弃疗了。。事实证明就改动几个字母。。。。
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; }