1. 程式人生 > >bzoj 4010 [HNOI2015]菜餚製作——貪心

bzoj 4010 [HNOI2015]菜餚製作——貪心

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=4010

和 bzoj 2535 差不多。因為當前怎麼決策與該點後面連的點的標號情況有關,所以按倒著的拓撲序決策。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1e5+5;
int T,n,m,hd[N],xnt,to[N],nxt[N];
int deg[N],ans[N]; bool
vis[N],ins[N],flag; int dfn[N],low[N],tim; priority_queue<int> q; int Mn(int a,int b){return a<b?a:b;} int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar(); return
fx?ret:-ret; } void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;deg[y]++;} void dfs(int cr) { vis[cr]=ins[cr]=1;dfn[cr]=low[cr]=++tim; for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]])dfs(v),low[cr]=Mn(low[cr],low[v]); else if(ins[v]){flag=1;return;} ins[cr]=0; } int main() { T
=rdn(); while(T--) { n=rdn();m=rdn(); xnt=0;flag=0; memset(hd,0,sizeof hd);memset(deg,0,sizeof deg); for(int i=1,u,v;i<=m;i++) u=rdn(),v=rdn(),add(v,u); memset(vis,0,sizeof vis);memset(ins,0,sizeof ins); tim=0; for(int i=1;i<=n;i++){if(!vis[i])dfs(i);if(flag)break;} if(flag){puts("Impossible!");continue;} for(int i=1;i<=n;i++)if(!deg[i])q.push(i); int p0=n; while(q.size()) { int k=q.top();q.pop(); ans[p0--]=k; for(int i=hd[k],v;i;i=nxt[i]) if(!(--deg[v=to[i]]))q.push(v); } for(int i=1;i<=n;i++)printf("%d ",ans[i]);puts(""); } return 0; }

 

[HNOI2015]菜餚製作