bzoj2535 [Noi2010]航空管制
由两行组成。
第一行包含 n个整数,表示一个可行的起飞序列,相邻两个整数用空格分隔。
输入数据保证至少存在一个可行的起飞序列。如果存在多个可行的方案,输出任意一个即可。
第二行包含 n个整数 t1, t2, „, tn,其中 ti表示航班i可能的最小起飞序号,相邻两个整数用空格分隔。
正解:贪心+堆。
表示蒟蒻的我只会做第一问,然而第二问也这么水。。
第一问很简单,反向拓扑序+大根堆,然后从后往前依次填序号就行。
第二问其实也不难。和第一问一样,只要我们把当前这个点卡住,不对它进行任何操作,当我们发现堆中取出的点没有办法再标号时,那这个标号就是询问点的最小标号。
然而优先队列被卡成狗,只好改成手写堆。。
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <cstdlib> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 #define inf (1<<30) 14 #define N (500010) 15 #define il inline 16 #define RG register 17 #define ll long long 18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 19 20 using namespace std; 21 22 struct edge{ int nt,to; }g[N]; 23 24 int head[N],cnt[N],d[N],k[N],a[N],b[N],Q[N],n,m,num,len; 25 26 il int gi(){ 27 RG int x=0,q=1; RG char ch=getchar(); 28 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 29 if (ch=='-') q=-1,ch=getchar(); 30 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); 31 return q*x; 32 } 33 34 il void insert(RG int from,RG int to){ 35 g[++num]=(edge){head[from],to},head[from]=num; return; 36 } 37 38 il void Push(RG int i){ 39 Q[++len]=i; RG int x=len; 40 while (x>>1){ 41 if (k[Q[x>>1]]>=k[Q[x]]) break; 42 swap(Q[x>>1],Q[x]),x>>=1; 43 } 44 return; 45 } 46 47 il void Pop(){ 48 Q[1]=Q[len--]; RG int x=1,v; 49 while ((x<<1)<=len){ 50 v=x<<1; if ((v|1)<=len && k[Q[v|1]]>k[Q[v]]) v|=1; 51 if (k[Q[x]]>=k[Q[v]]) break; swap(Q[x],Q[v]),x=v; 52 } 53 return; 54 } 55 56 il void solve(RG int s){ 57 len=0; 58 for (RG int i=1;i<=n;++i){ 59 cnt[i]=d[i]; if (i==s) cnt[i]=n; 60 if (!cnt[i]) Push(i); 61 } 62 for (RG int id=n;id;--id){ 63 if (!len){ b[s]=id; return; } RG int x=Q[1],v; Pop(); 64 if (!s) a[id]=x; else if (k[x]<id){ b[s]=id; return; } 65 for (RG int i=head[x];i;i=g[i].nt){ 66 v=g[i].to; if (!(--cnt[v])) Push(v); 67 } 68 } 69 return; 70 } 71 72 il void work(){ 73 n=gi(),m=gi(); for (RG int i=1;i<=n;++i) k[i]=gi(); 74 for (RG int i=1,u,v;i<=m;++i) u=gi(),v=gi(),insert(v,u),++d[u]; 75 for (RG int i=0;i<=n;++i) solve(i); 76 for (RG int i=1;i<=n;++i) printf("%d ",a[i]); puts(""); 77 for (RG int i=1;i<=n;++i) printf("%d ",b[i]); return; 78 } 79 80 int main(){ 81 File("plane"); 82 work(); 83 return 0; 84 }优质内容筛选与推荐>>