UVALive 3211 Now or later(二份答案+2-SAT)
2014-02-25 15:42
344 查看
题目:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1212
题目大意:有n架飞机要降落,可以选择 早着陆 或者 晚着陆 ,给你这n架飞机两种着陆的时刻表,让你安排,使得两架飞机着陆的时间间隔尽可能大,并输出这个时间。
解题思路:要求答案最大,很容易想到二分答案。然后就是判断这个答案可不可行,这只要做一遍2-SAT就行。再看看时限,时间复杂度为O(n*nlogT),过得去。
代码如下:
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN = 2222;
int t[MAXN][2];
struct Two_Sat
{
int n;
vector<int> G[MAXN<<1];
bool mark[MAXN<<1];
int S[MAXN<<1],c;
void init(int n)
{
this->n = n;
for(int i = 0;i < (n<<1);i++)
G[i].clear();
memset(mark,0,sizeof(mark));
}
void add_clause(int x,int x_val,int y,int y_val)
{
x = (x<<1)+x_val;
y = (y<<1)+y_val;
G[x].push_back(y^1);
G[y].push_back(x^1);
}
int dfs(int u)
{
if(mark[u^1]) return 0;
if(mark[u]) return 1;
mark[u] = 1;
S[c++] = u;
for(int i = 0;i < G[u].size();i++)
{
int v = G[u][i];
if(!dfs(v)) return 0;
}
return 1;
}
int solve()
{
for(int i = 0;i < (n<<1);i += 2)
{
if(!mark[i] && !mark[i+1])
{
c = 0;
if(!dfs(i))
{
while(c)
{
mark[S[--c]] = 0;
}
if(!dfs(i+1)) return 0;
}
}
}
return 1;
}
} two;
int check(int mid,int n)
{
two.init(n);
for(int i = 0;i < n;i++)
for(int a = 0;a < 2;a++)
for(int j = i+1;j < n;j++)
for(int b = 0;b < 2;b++)
if(abs(t[i][a] - t[j][b]) < mid)
{
two.add_clause(i,a^1,j,b^1);
}
return two.solve();
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i = 0;i < n;i++)
scanf("%d%d",&t[i][0],&t[i][1]);
int l = 0,r = 1e7;
int ans = 0;
while(l <= r)
{
int mid = (l+r)>>1;
if(check(mid,n))
{
ans = mid;
l = mid+1;
}
else r = mid-1;
}
printf("%d\n",ans);
}
return 0;
}
/*
2
1 10
4 14
*/
题目大意:有n架飞机要降落,可以选择 早着陆 或者 晚着陆 ,给你这n架飞机两种着陆的时刻表,让你安排,使得两架飞机着陆的时间间隔尽可能大,并输出这个时间。
解题思路:要求答案最大,很容易想到二分答案。然后就是判断这个答案可不可行,这只要做一遍2-SAT就行。再看看时限,时间复杂度为O(n*nlogT),过得去。
代码如下:
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN = 2222;
int t[MAXN][2];
struct Two_Sat
{
int n;
vector<int> G[MAXN<<1];
bool mark[MAXN<<1];
int S[MAXN<<1],c;
void init(int n)
{
this->n = n;
for(int i = 0;i < (n<<1);i++)
G[i].clear();
memset(mark,0,sizeof(mark));
}
void add_clause(int x,int x_val,int y,int y_val)
{
x = (x<<1)+x_val;
y = (y<<1)+y_val;
G[x].push_back(y^1);
G[y].push_back(x^1);
}
int dfs(int u)
{
if(mark[u^1]) return 0;
if(mark[u]) return 1;
mark[u] = 1;
S[c++] = u;
for(int i = 0;i < G[u].size();i++)
{
int v = G[u][i];
if(!dfs(v)) return 0;
}
return 1;
}
int solve()
{
for(int i = 0;i < (n<<1);i += 2)
{
if(!mark[i] && !mark[i+1])
{
c = 0;
if(!dfs(i))
{
while(c)
{
mark[S[--c]] = 0;
}
if(!dfs(i+1)) return 0;
}
}
}
return 1;
}
} two;
int check(int mid,int n)
{
two.init(n);
for(int i = 0;i < n;i++)
for(int a = 0;a < 2;a++)
for(int j = i+1;j < n;j++)
for(int b = 0;b < 2;b++)
if(abs(t[i][a] - t[j][b]) < mid)
{
two.add_clause(i,a^1,j,b^1);
}
return two.solve();
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i = 0;i < n;i++)
scanf("%d%d",&t[i][0],&t[i][1]);
int l = 0,r = 1e7;
int ans = 0;
while(l <= r)
{
int mid = (l+r)>>1;
if(check(mid,n))
{
ans = mid;
l = mid+1;
}
else r = mid-1;
}
printf("%d\n",ans);
}
return 0;
}
/*
2
1 10
4 14
*/
相关文章推荐
- 艺人分享减肥经
- background-position 用法详细介绍
- 开源学习 百度推送实战项目 友聊 (五)
- embed 元素 用javascript 控制 play stop的实现
- SDWebImage的源代码无法运行的问题
- [转]Win7下Eclipse中文字体太小
- openvswith Frequently Asked Questions
- 最短路总结
- 什么叫别让孩子输在起跑线上?! - 电子产品已成儿童“多动症”诱因
- Apache+Tomcat集群之环境搭建 .
- C# Dynamic 关键字学习
- 学习全智贤减肥
- 如何删除fgets(...)取到的字符串末尾的换行符?
- 坑爹的异常
- 3Sum Closest
- IplImage, CvMat, Mat 的关系和相互转换(转)
- 1033. To Fill or Not to Fill (25)
- 健身房减肥计划 科学快速燃脂
- 安卓手机铃声设置
- C#统计文章中单词的重复次数,并且按照次数从高到低排序返回(无法处理中文)