[BZOJ 4010] 菜肴制作
Link:
Solution:
思路挺妙的一题
一看到有先后的约束关系,肯定要拓扑排序
而且对所有的数要求依次最优(不是字典序最小),看起来贪心选最小的就可以了
但从前往后贪心会出现问题:
对于两个数$x,y$,其中$x<y$,如果$y$无约束关系,其会出现在$x$之前
为了解决这样的问题,发现只要反向建边,从后往前拓扑排序同时贪心选取最大的就行了
Code:
//by NewErA #include <bits/stdc++.h> using namespace std; const int MAXN=1e5+5; int T,n,m,in[MAXN]; vector<int> a[MAXN],res; int main() { scanf("%d",&T); while(T--) { memset(in,0,sizeof(in));res.clear(); for(int i=0;i<MAXN;i++) a[i].clear(); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y;scanf("%d%d",&x,&y); a[y].push_back(x);in[x]++; } priority_queue<int> que; for(int i=1;i<=n;i++) if(!in[i]) que.push(i); while(!que.empty()) { int v=que.top();que.pop();res.push_back(v); for(int i=0;i<a[v].size();i++) { in[a[v][i]]--; if(!in[a[v][i]]) que.push(a[v][i]); } } if(res.size()!=n) puts("Impossible!"); else { reverse(res.begin(),res.end()); for(int i=0;i<res.size();i++) printf("%d ",res[i]); puts(""); } } return 0; }