洛谷题目传送门

题目描述

有n架飞机需要着陆。每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种。第i架飞机的早着陆时间为Ei,晚着陆时间为Li,不得在其他时间着陆。你的任务是为这些飞机安排着陆方式,使得整个着陆计划尽量安全。换句话说,如果把所有飞机的实际着陆时间按照从早到晚的顺序排列,相邻两个着陆时间间隔的最值(称为安全间隔)应尽量大。

输入格式

输入包含若干组数据。每组数据第一行为飞机的数目n。以下n行每行两个整数,即早着陆时间和晚着陆时间。所有时间t 满足0<=t<=10^7。输入结束标志为文件结束符(EOF)。

输出格式

对于每组数据,输出安全间隔的最大值。(记得换行)

输入输出样例

输入
10
44 156
153 182
48 109
160 201
55 186
54 207
55 165
17 58
132 160
87 197
 
 
输出
 10

  

说明/提示

n <= 2000; 剩下的所有数据保证不超过int范围

首先,从题目的要求来看,xxxx尽量大,xxxx尽量小,一般这种要求我们可以考虑二分查找答案。(套路)

于是,题目就成了判定:是否能使相邻的着陆时间不小于P,即我们目前二分枚举的时间。

继续看题,每种飞机有两种着陆方式:早着陆和晚着陆,考虑分别用0和1表示。

对于这种含有“或”的题,考虑用2—SAT问题进行求解。

建图:

  每一个节点v表示一种选择,一架飞机我们可以拆成两个点:早   与    晚。

   枚举每架飞机和它后面飞机的情况:如果两个时间相差小于P,则连边,表明选择第一种情况就必须选择第二种情况。(在枚举的时候应用for循环从小到大,优先早着陆,尽量贴近P,防止浪费时间)。

跑图:

  建好图之后,要做的就是跑图了。如何跑?当然是直接套用2—SAT问题的模板:用Tarjan强联通算法.

   如建图中所说,我们的‘边’代表的是必须选择。那么,如果我们选择一架飞机的“0”,然后经过一系列传导,又必须选择‘1’,怎么办?(凉拌)

           如果出现这种情况,自相矛盾,那么,原问题肯定无解!!!

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + ; struct edge{
int u,v,next;
}e[maxn << ];
//全部开两倍!!!有两倍的点
int f[maxn << ],low[maxn << ],dfn[maxn << ];
int scc[maxn << ];
bool vis[maxn << ];
int n,cac,cnt,m,top;
stack <int> stack1;
int T[maxn][]; void clean(){//不要被吓到了
for(int i = ;i <= * n; i++){
f[i] = dfn[i] = ;
}
cac = ;
top = ;
return;
} int jueduizhi(int x){
if(x < )x = -x;
return x;
} //-------------------------以下才是重点 void add(int u,int v){
top++;
e[top].u = u;//这个点(起点)
e[top].v = v;//它连向的那个点(终点)
e[top].next = f[u];
f[u] = top;
return;
} void tarjan(int now){
low[now] = dfn[now] = ++cac;//初始化用的
stack1.push(now);
vis[now] = ;
for(int i = f[now]; i ; i = e[i].next){
int v = e[i].v;//有连边
if(!dfn[v]){
tarjan(v);
low[now] = min(low[now],low[v]);
}else if(vis[v])
low[now] = min(low[now],dfn[v]);
}
if(low[now] == dfn[now]){
int cur;
cnt++;//是第几个强连通 ??
do{
cur = stack1.top();
stack1.pop();
vis[cur] = ;
scc[cur] = cnt;//记录每个点所在的强连通
}while(now != cur);
}
} bool two_SAT(){
for(int i = ; i <= * n; i++)
if(!dfn[i] )
tarjan(i);//tarjan找强连通分量
for(int i = ; i <= n; i++)
if(scc[i] == scc[i + n])return ;
//a条件和非a条件在同一个强连通分量,原问题无解
return ;
} bool test(int diff){
clean();
for(int i = ;i <= n; i++)//枚举每架飞机
for(int aval = ;aval < ; aval++)//早还是晚?
for(int j = i + ;j <= n; j++)//往下枚举后面的飞机
for(int bvbl = ;bvbl < ; bvbl++){//一样,分两种情况
if(jueduizhi(T[i][aval] - T[j][bvbl]) < diff){
int a = i,b = j;
int nota = aval ^ ,notb = bvbl ^ ;
add(a + nota * n,b + bvbl * n);
add(b + notb * n,a + aval * n);
}
}
return two_SAT();
} int main(){
// freopen("hh.txt","r",stdin);
while(scanf("%d",&n) != EOF && n){
int l = ,r = ;
for(int i = ;i <= n; i++)
for(int a = ;a < ; a++){
scanf("%d",&T[i][a]);
r = max(r,T[i][a]);
}
while(l < r){
int mid = l + (r - l + ) / ;//必须向上取整,不然全部爆0
//int mid = l + r >> 1;
if(test(mid)) l = mid;
else r = mid - ;
}
printf("%d\n",l);
}
return ;
}

   luogu那道题是自己手打上传的,数据可能有点毒瘤。。。

飞机调度 Now or Later? LA 3211 (2-SAT问题)的更多相关文章

  1. LA 3211 飞机调度

    题目链接:http://vjudge.net/contest/142615#problem/A 题意:n架飞机,每架可选择两个着落时间.安排一个着陆时间表,使得着陆间隔的最小值最大. 分析: 最小值最 ...

  2. LA 3211 飞机调度(2—SAT)

    https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间 ...

  3. 【LOJ】#2077. 「JSOI2016」飞机调度

    题解 考虑一架飞机飞完自己之后还能飞到哪些航线,用floyd求两点最短路 这个图建出来是个DAG,求最小路径覆盖即可,二分图匹配 注意判断时是航班的起飞时刻+直飞时间+加油时间+最短路时间 代码 #i ...

  4. 【LA3211 训练指南】飞机调度 【2-sat】

    题意 有n嫁飞机需要着陆.每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种.第i架飞机的早着陆时间为Ei,晚着陆时间为Li,不得在其他时间着陆.你的任务是为这些飞机安排着陆方式,使 ...

  5. LA3211 飞机调度 Now or later-二分法&TwoSet

    https://vjudge.net/problem/UVALive-3211 As you must have experienced, instead of landing immediately ...

  6. LA 3211

    As you must have experienced, instead of landing immediately, an aircraft sometimes waits in a holdi ...

  7. BZOJ 4853 [Jsoi2016]飞机调度

    题解: 我严重怀疑语文水平(自己的和出题人的) 把航线按照拓扑关系建立DAG 然后最小路径覆盖 为什么两条首尾相接航线之间不用维护???? #include<iostream> #incl ...

  8. 2-SAT 问题与解法小结

    2-SAT 问题与解法小结 这个算法十分的奇妙qwq... 将一类判定问题转换为图论问题,然后就很容易解决了. 本文有一些地方摘录了一下赵爽<2-SAT解法浅析> (侵删) 一些概念: \ ...

  9. (纪录片)现代生活的秘密规则:算法 The Secret Rules of Modern Living: Algorithms

    简介: The Secret Rules of Modern Living: Algorithms (2015) 导演: David Briggs主演: Marcus du Sautoy类型: 纪录片 ...

随机推荐

  1. CF思维联系--CodeForces -214C (拓扑排序+思维+贪心)

    ACM思维题训练集合 Furik and Rubik love playing computer games. Furik has recently found a new game that gre ...

  2. CodeForces - 1058D D. Vasya and Triangle

    D. Vasya and Triangle time limit per test1 second memory limit per test256 megabytes inputstandard i ...

  3. unittest(@classmethod 装饰器)

    1.前言: 前面讲到unittest里面setUp可以在每次执行用例前执行,这样有效的减少了代码量,但是有个弊端,比如打开浏览器操作,每次执行用例时候都会重新打开,这样就会浪费很多时间. 于是就想是不 ...

  4. 1年之后的拿高工资的资本,Java线程

    只要开启线程,都会开启一块对应的栈内存,然后进行同步执行. -- 谈斌 线程是CPU用来处理程序的资源,线程的执行是抢占式的. 线程开启方式: 创建一个类,继承Thread类.重写 run(), 并在 ...

  5. 002_python的in,while else,格式化输出,逻辑运算符,int与bool转换,编码

    数据 1.什么是数据? x=10,10是我们要存储的数据 2.为何数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3.数据类型 数字 字符串 列表 元组 字典 集合 ...

  6. 【带着canvas去流浪(15)】threejs fundamentals翻译系列1-scene graph

    示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 目录 ...

  7. Git使用教程之SSH连接方式配置(二)

    什么是GitHub?这个网站就是提供Git仓库托管服务的. 什么是SSH Key?你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,大白话理解就是这两个仓库如果要进行远程同步,则我们需 ...

  8. JDBC09 CLOB文本大对象

    CLOB(Character Large Object) -用于储存大量的文本数据 BLOB(Binary Large Object) -用于存储大量的二进制数据 -大字段有些特殊,不同数据处理的方式 ...

  9. 设计模式之GOF23访问者模式

    访问者模式Visitor 模式动机:对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接口),对于该集合中的对象,可以接受一类称为访问者的对象来访问,不同访问者的访问方式也不同 定义 ...

  10. HMM-维特比算法理解与实现(python)

    HMM-前向后向算法理解与实现(python) HMM-维特比算法理解与实现(python) 解码问题 给定观测序列 \(O=O_1O_2...O_T\),模型 \(\lambda (A,B,\pi) ...