题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2535

https://www.lydsy.com/JudgeOnline/problem.php?id=2109

这个题,如果正着考虑,也就是先考虑放在前面的再考虑放在后面的,决策时会有矛盾;
也就是,如果要求 pos[a] < pos[b],则先考虑放 a,因为许多点放在 a 后面,所以 a 尽量往前放可以给它们留出空位;
但又有限制最晚起飞时间,那么先考虑的 a 应该尽量放在靠近它最晚起飞时间的地方,以免后面的点无法满足起飞时间的限制;
于是尽量往前放和尽量往后放形成了矛盾,无法决策;
所以需要转化一个限制,不妨对于 pos[a] < pos[b],先决策 b;
于是两个限制合起来的要求就都变成尽量往后放了(真神奇);
所以我们就这样倒着做,一定能得到合法的序列;
然后考虑每个点的可能最前位置,其实就是做的过程中把这个点以及它限制的点都暂时去掉,让其他点放好,那么不能再放的时候就意味着只有放上这个点才能继续,这时这个点按刚才做法找到的位置就是它的最前位置(其他点已经尽量把它的可行位置挤到前面了);
注意放点位置是最晚起飞时间和限制它的点的起飞时间取 min 的!
注意答案是起飞序列!而不是每个点的起飞位置!
如果用 set 找某位置前面第一个空位会很慢,还是并查集好。
代码如下:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<queue>
  5. #include<set>
  6. using namespace std;
  7. int const xn=,xm=;
  8. int n,m,hd[xn],ct,to[xm],nxt[xm],deg[xn],tmp[xn],ans[xn],d[xn],mn[xn];
  9. struct N{
  10. int v,id;
  11. N(int v=,int i=):v(v),id(i) {}
  12. };
  13. queue<int>q;
  14. set<int>st;
  15. set<int>::iterator it;
  16. int rd()
  17. {
  18. int ret=,f=; char ch=getchar();
  19. while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
  20. while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
  21. return f?ret:-ret;
  22. }
  23. void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
  24. void topo(int nw)
  25. {
  26. for(int i=;i<=n;i++)
  27. {
  28. mn[i]=min(n,d[i]); tmp[i]=deg[i];
  29. if(!tmp[i]&&i!=nw)q.push(i);
  30. }
  31. while(q.size())
  32. {
  33. int x=q.front(); q.pop();
  34. it=st.lower_bound(n-mn[x]+);
  35. int tim=*it;
  36. //ans[x]=n-tim+1; //!!!
  37. ans[n-tim+]=x;
  38. st.erase(tim);
  39. for(int i=hd[x],u;i;i=nxt[i])
  40. {
  41. if((u=to[i])==nw)continue;
  42. tmp[u]--; mn[u]=min(mn[u],mn[x]);//!!
  43. if(!tmp[u])q.push(u);
  44. }
  45. }
  46. }
  47. int solve(int x)
  48. {
  49. st.clear();
  50. for(int i=;i<=n;i++)st.insert(i);
  51. topo(x);
  52. it=st.lower_bound(n-d[x]+);
  53. return n-*it+;
  54. }
  55. int main()
  56. {
  57. n=rd(); m=rd();
  58. for(int i=;i<=n;i++)d[i]=rd(),st.insert(i);
  59. for(int i=,x,y;i<=m;i++)x=rd(),y=rd(),add(y,x),deg[x]++;
  60. topo();
  61. for(int i=;i<=n;i++)printf("%d ",ans[i]); puts("");
  62. for(int i=;i<=n;i++)printf("%d ",solve(i)); puts("");
  63. return ;
  64. }

set

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<queue>
  5. using namespace std;
  6. int const xn=,xm=;
  7. int n,m,hd[xn],ct,to[xm],nxt[xm],deg[xn],tmp[xn],ans[xn],d[xn],mn[xn];
  8. int fa[xn],q[xn];
  9. int rd()
  10. {
  11. int ret=,f=; char ch=getchar();
  12. while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
  13. while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
  14. return f?ret:-ret;
  15. }
  16. void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
  17. int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
  18. void topo(int nw)
  19. {
  20. int cnt=;
  21. for(int i=;i<=n;i++)
  22. {
  23. mn[i]=min(n,d[i]); tmp[i]=deg[i]; fa[i]=i;
  24. if(!tmp[i]&&i!=nw)q[++cnt]=i;
  25. }
  26. while(cnt)
  27. {
  28. int x=q[cnt--]; int tim=find(mn[x]);
  29. ans[tim]=x; fa[tim]=tim-;
  30. for(int i=hd[x],u;i;i=nxt[i])
  31. {
  32. if((u=to[i])==nw)continue;
  33. tmp[u]--; mn[u]=min(mn[u],mn[x]);//!!
  34. if(!tmp[u])q[++cnt]=u;
  35. }
  36. }
  37. }
  38. int solve(int x)
  39. {
  40. topo(x); return find(d[x]);
  41. }
  42. int main()
  43. {
  44. n=rd(); m=rd();
  45. for(int i=;i<=n;i++)d[i]=rd();
  46. for(int i=,x,y;i<=m;i++)x=rd(),y=rd(),add(y,x),deg[x]++;
  47. topo();
  48. for(int i=;i<=n;i++)printf("%d ",ans[i]); puts("");
  49. for(int i=;i<=n;i++)printf("%d ",solve(i)); puts("");
  50. return ;
  51. }

bzoj 2535 & bzoj 2109 航空管制 —— 贪心+拓扑序的更多相关文章

  1. BZOJ 2535: [Noi2010]Plane 航空管制2

    Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此,小X表示很不满意. 在这次来烟台的路上 ...

  2. [BZOJ2109][NOI2010]航空管制(贪心+拓扑)

    2109: [Noi2010]Plane 航空管制 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1227  Solved: 510[Submit][ ...

  3. bzoj 2535: [Noi2010]Plane 航空管制2【拓扑排序+堆】

    有个容易混的概念就是第一问的答案不是k[i]字典序最小即可,是要求k[i]大的尽量靠后,因为这里前面选的时候是对后面有影响的(比如两条链a->b c->d,ka=4,kb=2,kc=3,k ...

  4. bzoj 2535 && bzoj 2109 [Noi2010]Plane 航空管制——贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2535 https://www.lydsy.com/JudgeOnline/problem.p ...

  5. 2109&2535: [Noi2010]Plane 航空管制 - BZOJ

    Description世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此,小X表示很不满意. 在这次来烟台的路上, ...

  6. BZOJ 2109 航空管制(拓扑排序+贪心)

    绝世好题啊.. 题意:给出一个DAG,和每个点要求出现在这个DAG里面的拓扑排序的位置<=ti,求出所有可能的拓扑排序里面每个点出现的位置的最小值. 正着做不好做,考虑反着做,建立这个图的反图. ...

  7. BZOJ2535: [Noi2010]Plane 航空管制2(拓扑排序 贪心)

    题意 题目链接 Sol 非常妙的一道题. 首先不难想到拓扑排序,但是直接对原图按\(k\)从小到大拓扑排序是错的.因为当前的\(k\)大并不意味着后面的点\(k\)也大 但是在反图上按\(k\)从大到 ...

  8. BZOJ.2109.[NOI2010]航空管制(拓扑 贪心)

    题目链接 双倍经验(没有第一问) \(Description\) \(Solution\) 第一问拓扑排序即可. 第二问,即让一个元素在拓扑序中尽量靠前,好像不好做. 但是可以让一个元素出现尽量靠后. ...

  9. bzoj 2109: [Noi2010]Plane 航空管制

    Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频 发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此, 小X表示很不满意. 在这次来烟台的 ...

随机推荐

  1. 【译】StackOverflow——Java 中的 finally 代码块是否总会被执行?

    问题 有一个 try/catch 代码块,其中包含一个打印语句.finally代码块总会被调用么? 示例: try { something(); return success; } catch (Ex ...

  2. 洛谷P2402 奶牛隐藏

    洛谷P2402 奶牛隐藏 题目背景 这本是一个非常简单的问题,然而奶牛们由于下雨已经非常混乱,无法完成这一计算,于是这个任务就交给了你.(奶牛混乱的原因看题目描述) 题目描述 在一个农场里有n块田地. ...

  3. 忘记apple id如何更新应用?

    最近ytkah的app有很多更新提示,之前注册的apple id好久没登录了,突然提示说登录需要验证安全问题,哪还记得噢,最要命的是邮箱收到的加密邮件也需要验证.重新注册一个吧,这次要注意保存相关信息 ...

  4. memcpy使用

    void memcpy(void dest, const void *src, size_t n); 功能编辑 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置 ...

  5. 使用JavaScript定义一个微信小程序插件样例

    var wxTimer = new wxTimer({ beginTime: "00:00:20", complete: function () { wx.redirectTo({ ...

  6. xutils3文件上传、下载、get、post请求

    @ContentView(R.layout.activity_xutils3_net) public class XUtils3NetActivity extends Activity { @View ...

  7. Flex自定义组件开发

    一般情况下需要组件重写都是由于以下2个原因:1.在FLEX已有组件无法满足业务需求,或是需要更改其可视化外观等特性时,直接进行继承扩展.2.为了模块化设计或进一步重用,需要对FLEX组件进行组合.而F ...

  8. EntityFramework 学习 一 DBEntityEntry

    DbEntityEntry是一个重要的类,用来获取各种各样的实体信息 可以通过DBContext的Entry方法获取DbEntityEntry的实例 DBEntityEntry studentEntr ...

  9. Docker-为镜像添加SSH服务

    进入容器的办法有很多,包括exec.attach等命令,但是这些命令都无法解决远程管理容器的问题,因此,需要SSH的支持 基于commit命令创建 docker提供了docker commit命令,支 ...

  10. linux学习系列三

    1. 账户与账户安全 账户和组是操作系统的基本概念,linux的组有基本组和附加组之分,一个用户只可以加入到一个基本组中国,但是可以加入到多个附加组中.创建用户时,系统默认会自动创建同名的组,并设置用 ...