LA 3211 Now or Later(2-SAT问题)

来源:互联网 发布:宋仲基宋慧乔婚礼知乎 编辑:程序博客网 时间:2024/05/01 18:40

题目大意:

    N架飞机需要着陆,每架飞机都有一个早着陆时间和晚着陆时间,安排飞机着陆方式,使得相邻两个着陆时间间隔的最小值最大。

解题思路:

   "最小值最大问题”典型的处理方式就是二分查找最终答案P,这样将问题转化为是否存在一个安排方案,使得任意两个相邻着陆时间的间隔都不小于P。

这个问题可以进一步转化为一个2-SAT问题,将两个时间差小于P的点相连,判断是否存在解。

#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>#include <vector>#define LL long longusing namespace std;const int maxn = 10000 + 10;class TwoSAT{public:int n;vector<int> G[maxn*2];bool mark[maxn*2];int S[maxn*2] , c;bool dfs(int x){if(mark[x^1]) return false;if(mark[x]) return true;mark[x] = true;S[c++] = x;for(int i=0;i<G[x].size();i++)if(!dfs(G[x][i])) return false;return true;}void init(int n){this->n = n;for(int i=0;i<=2*n;i++) G[i].clear();memset(mark,0,sizeof(mark));}void AddEdge(int x,int y){G[x^1].push_back(y);G[y^1].push_back(x);}bool solve(){for(int i=0;i<n*2;i+=2)if(!mark[i] && !mark[i+1]){c = 0;if(!dfs(i)){while(c > 0) mark[S[--c]] = false;if(!dfs(i+1)) return false;}}return true;}};TwoSAT g;int n , T[maxn][2];bool test(int limit){g.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]) < limit)g.AddEdge(2*i+a,2*j+b);}}}}return g.solve();}int main(){while(scanf("%d",&n)!=EOF && n){int L = 0 , R = 0;for(int i=0;i<n;i++){for(int j=0;j<2;j++){scanf("%d",&T[i][j]);R = max(R,T[i][j]);}}while(L < R){int m = L + (R - L + 1) / 2;if(test(m)) L  = m ;else R = m - 1;}printf("%d\n",R);}return 0;}

0 0
原创粉丝点击