bzoj 2535 & bzoj 2109 航空管制 —— 贪心+拓扑序
题目: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 找某位置前面第一个空位会很慢,还是并查集好。
代码如下:
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- #include<set>
- using namespace std;
- int const xn=,xm=;
- int n,m,hd[xn],ct,to[xm],nxt[xm],deg[xn],tmp[xn],ans[xn],d[xn],mn[xn];
- struct N{
- int v,id;
- N(int v=,int i=):v(v),id(i) {}
- };
- queue<int>q;
- set<int>st;
- set<int>::iterator it;
- int rd()
- {
- int ret=,f=; char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
- while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
- return f?ret:-ret;
- }
- void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
- void topo(int nw)
- {
- for(int i=;i<=n;i++)
- {
- mn[i]=min(n,d[i]); tmp[i]=deg[i];
- if(!tmp[i]&&i!=nw)q.push(i);
- }
- while(q.size())
- {
- int x=q.front(); q.pop();
- it=st.lower_bound(n-mn[x]+);
- int tim=*it;
- //ans[x]=n-tim+1; //!!!
- ans[n-tim+]=x;
- st.erase(tim);
- for(int i=hd[x],u;i;i=nxt[i])
- {
- if((u=to[i])==nw)continue;
- tmp[u]--; mn[u]=min(mn[u],mn[x]);//!!
- if(!tmp[u])q.push(u);
- }
- }
- }
- int solve(int x)
- {
- st.clear();
- for(int i=;i<=n;i++)st.insert(i);
- topo(x);
- it=st.lower_bound(n-d[x]+);
- return n-*it+;
- }
- int main()
- {
- n=rd(); m=rd();
- for(int i=;i<=n;i++)d[i]=rd(),st.insert(i);
- for(int i=,x,y;i<=m;i++)x=rd(),y=rd(),add(y,x),deg[x]++;
- topo();
- for(int i=;i<=n;i++)printf("%d ",ans[i]); puts("");
- for(int i=;i<=n;i++)printf("%d ",solve(i)); puts("");
- return ;
- }
set
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- using namespace std;
- int const xn=,xm=;
- int n,m,hd[xn],ct,to[xm],nxt[xm],deg[xn],tmp[xn],ans[xn],d[xn],mn[xn];
- int fa[xn],q[xn];
- int rd()
- {
- int ret=,f=; char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
- while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
- return f?ret:-ret;
- }
- void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
- int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
- void topo(int nw)
- {
- int cnt=;
- for(int i=;i<=n;i++)
- {
- mn[i]=min(n,d[i]); tmp[i]=deg[i]; fa[i]=i;
- if(!tmp[i]&&i!=nw)q[++cnt]=i;
- }
- while(cnt)
- {
- int x=q[cnt--]; int tim=find(mn[x]);
- ans[tim]=x; fa[tim]=tim-;
- for(int i=hd[x],u;i;i=nxt[i])
- {
- if((u=to[i])==nw)continue;
- tmp[u]--; mn[u]=min(mn[u],mn[x]);//!!
- if(!tmp[u])q[++cnt]=u;
- }
- }
- }
- int solve(int x)
- {
- topo(x); return find(d[x]);
- }
- int main()
- {
- n=rd(); m=rd();
- for(int i=;i<=n;i++)d[i]=rd();
- for(int i=,x,y;i<=m;i++)x=rd(),y=rd(),add(y,x),deg[x]++;
- topo();
- for(int i=;i<=n;i++)printf("%d ",ans[i]); puts("");
- for(int i=;i<=n;i++)printf("%d ",solve(i)); puts("");
- return ;
- }
bzoj 2535 & bzoj 2109 航空管制 —— 贪心+拓扑序的更多相关文章
- BZOJ 2535: [Noi2010]Plane 航空管制2
Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此,小X表示很不满意. 在这次来烟台的路上 ...
- [BZOJ2109][NOI2010]航空管制(贪心+拓扑)
2109: [Noi2010]Plane 航空管制 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1227 Solved: 510[Submit][ ...
- bzoj 2535: [Noi2010]Plane 航空管制2【拓扑排序+堆】
有个容易混的概念就是第一问的答案不是k[i]字典序最小即可,是要求k[i]大的尽量靠后,因为这里前面选的时候是对后面有影响的(比如两条链a->b c->d,ka=4,kb=2,kc=3,k ...
- bzoj 2535 && bzoj 2109 [Noi2010]Plane 航空管制——贪心
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2535 https://www.lydsy.com/JudgeOnline/problem.p ...
- 2109&2535: [Noi2010]Plane 航空管制 - BZOJ
Description世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此,小X表示很不满意. 在这次来烟台的路上, ...
- BZOJ 2109 航空管制(拓扑排序+贪心)
绝世好题啊.. 题意:给出一个DAG,和每个点要求出现在这个DAG里面的拓扑排序的位置<=ti,求出所有可能的拓扑排序里面每个点出现的位置的最小值. 正着做不好做,考虑反着做,建立这个图的反图. ...
- BZOJ2535: [Noi2010]Plane 航空管制2(拓扑排序 贪心)
题意 题目链接 Sol 非常妙的一道题. 首先不难想到拓扑排序,但是直接对原图按\(k\)从小到大拓扑排序是错的.因为当前的\(k\)大并不意味着后面的点\(k\)也大 但是在反图上按\(k\)从大到 ...
- BZOJ.2109.[NOI2010]航空管制(拓扑 贪心)
题目链接 双倍经验(没有第一问) \(Description\) \(Solution\) 第一问拓扑排序即可. 第二问,即让一个元素在拓扑序中尽量靠前,好像不好做. 但是可以让一个元素出现尽量靠后. ...
- bzoj 2109: [Noi2010]Plane 航空管制
Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频 发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此, 小X表示很不满意. 在这次来烟台的 ...
随机推荐
- 【译】StackOverflow——Java 中的 finally 代码块是否总会被执行?
问题 有一个 try/catch 代码块,其中包含一个打印语句.finally代码块总会被调用么? 示例: try { something(); return success; } catch (Ex ...
- 洛谷P2402 奶牛隐藏
洛谷P2402 奶牛隐藏 题目背景 这本是一个非常简单的问题,然而奶牛们由于下雨已经非常混乱,无法完成这一计算,于是这个任务就交给了你.(奶牛混乱的原因看题目描述) 题目描述 在一个农场里有n块田地. ...
- 忘记apple id如何更新应用?
最近ytkah的app有很多更新提示,之前注册的apple id好久没登录了,突然提示说登录需要验证安全问题,哪还记得噢,最要命的是邮箱收到的加密邮件也需要验证.重新注册一个吧,这次要注意保存相关信息 ...
- memcpy使用
void memcpy(void dest, const void *src, size_t n); 功能编辑 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置 ...
- 使用JavaScript定义一个微信小程序插件样例
var wxTimer = new wxTimer({ beginTime: "00:00:20", complete: function () { wx.redirectTo({ ...
- xutils3文件上传、下载、get、post请求
@ContentView(R.layout.activity_xutils3_net) public class XUtils3NetActivity extends Activity { @View ...
- Flex自定义组件开发
一般情况下需要组件重写都是由于以下2个原因:1.在FLEX已有组件无法满足业务需求,或是需要更改其可视化外观等特性时,直接进行继承扩展.2.为了模块化设计或进一步重用,需要对FLEX组件进行组合.而F ...
- EntityFramework 学习 一 DBEntityEntry
DbEntityEntry是一个重要的类,用来获取各种各样的实体信息 可以通过DBContext的Entry方法获取DbEntityEntry的实例 DBEntityEntry studentEntr ...
- Docker-为镜像添加SSH服务
进入容器的办法有很多,包括exec.attach等命令,但是这些命令都无法解决远程管理容器的问题,因此,需要SSH的支持 基于commit命令创建 docker提供了docker commit命令,支 ...
- linux学习系列三
1. 账户与账户安全 账户和组是操作系统的基本概念,linux的组有基本组和附加组之分,一个用户只可以加入到一个基本组中国,但是可以加入到多个附加组中.创建用户时,系统默认会自动创建同名的组,并设置用 ...