和P3243有相似的地方,但是不懂
upd:第二问和P3243有相似,第一问我们正着拓扑排序会进入局部最优解,每次从堆顶取的最小值不一定是全局最小值,可能某点稍大但是它所连接的点小
#include<bits/stdc++.h> #define R register using namespace std; const int maxn=2009; inline int read(){ R int ret=0,fix=1;R char ch; while(!isdigit(ch=getchar()))fix=ch=='-'?-1:fix; do ret=(ret<<1)+(ret<<3)+ch-'0'; while(isdigit(ch=getchar())); return fix*ret; } int n,m; struct noe{ int v,nxt; }e[10009]; int head[maxn],cnt; inline void add(int u,int v){ e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt; } int k[maxn],in[maxn],tmp[maxn]; struct node{ int x,d; node(){} node(int xx,int dd){x=xx;d=dd;} bool operator <(const node&t)const{ return d<t.d; } }; priority_queue<node>q; inline int work(int x){ memcpy(in,tmp,sizeof(in)); in[x]=n;//忽略要求的飞机 while(!q.empty())q.pop(); for(R int i=1;i<=n;i++)if(!in[i])q.push(node(i,k[i])); for(R int i=n;i>=1;i--){ if(q.empty()||q.top().d<i)return i;//没有飞机可起飞了 int x=q.top().x;q.pop(); for(R int i=head[x];i;i=e[i].nxt){ if(!--in[e[i].v])q.push(node(e[i].v,k[e[i].v])); } } } int ans[maxn],ccc; int main(){ // freopen("testdata (7).in","r",stdin); // freopen("test.out","w",stdout); scanf("%d%d",&n,&m); for(R int i=1;i<=n;i++)k[i]=read(); for(R int i=1,u,v;i<=m;i++){ u=read();v=read(); add(v,u);in[u]++; } memcpy(tmp,in,sizeof(in)); for(R int i=1;i<=n;i++)if(!in[i])q.push(node(i,k[i])); while(!q.empty()){ int x=q.top().x;q.pop();ans[++ccc]=x; for(R int i=head[x];i;i=e[i].nxt){ if(!--in[e[i].v])q.push(node(e[i].v,k[e[i].v])); } } for(R int i=ccc;i>=1;i--)printf("%d ",ans[i]);puts(""); for(R int i=1;i<=n;i++)printf("%d ",work(i)); }