您的位置:首页 > 其它

uva 1146(2-SAT+二分判断)

2014-02-01 13:44 363 查看
题意:有n架飞机需要着陆,每架飞机都有两个时间可以选择,早和晚。告诉你每架飞机的这两个时间,然后我们定义相邻两架飞机着陆时间间隔的最小值为安全间隔。问你安全间隔最大能为多少。

思路:一个典型的2-sat+二分判断的问题。首先我们对安全间隔二分答案,然后再2-sat判断可行性。思路理清的话没什么难度。

代码如下:

/**************************************************
* Author     : xiaohao Z
* Blog     : http://www.cnblogs.com/shu-xiaohao/ * Last modified : 2014-02-01 12:12
* Filename     : uva_1146.cpp
* Description     :
* ************************************************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define MP(a, b) make_pair(a, b)
#define PB(a) push_back(a)

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<unsigned int,unsigned int> puu;
typedef pair<int, double> pid;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;

const int INF = 0x3f3f3f3f;
const double eps = 1E-6;
const int LEN = 10020;
vector<int> Map[LEN], rMap[LEN], vs;
int n, vis[LEN], tim[LEN][2], sccn[LEN];

int abs(int a){
return a>0?a:-a;
}

void dfs(int v){
vis[v] = 1;
for(int i=0; i<Map[v].size(); i++)
if(!vis[Map[v][i]])dfs(Map[v][i]);
vs.PB(v);
}

void rdfs(int v, int f){
vis[v] = 1;
sccn[v] = f;
for(int i=0; i<rMap[v].size(); i++)
if(!vis[rMap[v][i]]) rdfs(rMap[v][i], f);
}

int scc()
{
memset(vis, 0, sizeof vis);
vs.clear();
for(int i=0; i<n*2; i++) if(!vis[i])dfs(i);
memset(vis, 0, sizeof vis);
int k = 0;
for(int i=vs.size()-1; i>=0; i--)if(!vis[vs[i]])rdfs(vs[i], k++);
return k;
}

void addedge(int a, int b){
Map[a].PB(b);
rMap[b].PB(a);
}

bool Judge(int bak){
for(int i=0; i<LEN; i++) Map[i].clear();
for(int i=0; i<LEN; i++) rMap[i].clear();
for(int i=0; i<n; i++)
for(int j=0; j<n; j++){
if(i == j) continue;
int a = i*2, fa = i*2+1, b = j*2, fb = j*2+1;
if(abs(tim[i][0]-tim[j][0]) < bak){
addedge(a, fb);
addedge(b, fa);
}
if(abs(tim[i][0]-tim[j][1]) < bak){
addedge(a, b);
addedge(fb, fa);
}
if(abs(tim[i][1]-tim[j][0]) < bak){
addedge(fa, fb);
addedge(b, a);
}
if(abs(tim[i][1]-tim[j][1]) < bak){
addedge(fb, a);
addedge(fa, b);
}
}
scc();
for(int i=0; i<n*2; i+=2)
if(sccn[i] == sccn[i+1]) return false;
return true;
}

int main()
{
//    freopen("in.txt", "r", stdin);

while(scanf("%d", &n)!=EOF){
for(int i=0; i<n; i++)
scanf("%d%d", &tim[i][0], &tim[i][1]);
int l = 0, r = 10000000;
while(l<r){
int mid = (l+r+1)/2;
if(Judge(mid))l = mid;
else r = mid-1;
}
printf("%d\n", l);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: