用拓扑排序搞
最早什么时候起飞就倒过来建反图然后一个劲的从后面加直到不能加为止
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef pair<int,int> abcd;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int M=10005;
const int N=2005;
struct edge{
int u,v,next;
}G[M<<1];
int head[N],inum;
inline void add(int u,int v,int p){
G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
}
priority_queue<abcd,vector<abcd>,greater<abcd> > Q;
int n,m;
int c[N],deg[N],ideg[N];
int pnt,lst[N];
#define V G[p].v
inline void Topo1(){
for (int i=1;i<=n;i++) if (!deg[i]) Q.push(abcd(c[i],i));
while (!Q.empty()){
int u=Q.top().second; Q.pop();
lst[++pnt]=u;
for (int p=head[u];p;p=G[p].next)
if (!(--deg[V]))
Q.push(abcd(c[V],V));
}
reverse(lst+1,lst+pnt+1);
for (int i=1;i<=n;i++) printf("%d ",lst[i]);
printf("\n");
memcpy(deg,ideg,sizeof(deg));
}
inline void Topo2(int x){
for (int i=1;i<=n;i++) if (!deg[i]) Q.push(abcd(c[i],i));
pnt=0; cl(lst);
while (!Q.empty()){
int u=Q.top().second; Q.pop();
if (u==x) continue;
if (c[u]>pnt+1) break;
lst[++pnt]=u;
for (int p=head[u];p;p=G[p].next)
if (!(--deg[V]))
Q.push(abcd(c[V],V));
}
while (!Q.empty()) Q.pop();
printf("%d ",n-pnt);
memcpy(deg,ideg,sizeof(deg));
}
int main(){
int iu,iv;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m);
for (int i=1;i<=n;i++) read(c[i]),c[i]=n-c[i]+1;
for (int i=1;i<=m;i++){
read(iu),read(iv);
add(iv,iu,++inum),deg[iu]++;
}
memcpy(ideg,deg,sizeof(deg));
Topo1();
for (int i=1;i<=n;i++)
Topo2(i);
return 0;
}