题意:
一座飞机场要降落飞机,每架飞机有两种降落方式:早降落和晚降落。
现在要安排飞机的降落使得两个飞机降落时间的最小值最大。
输出这个最小值。
思路:
最小值最大化,可以想到答案需要二分。
然后就是如何判断一个时间是否满足条件。一个飞机要么早降落,要么晚降落,所以就是一个为真,另一个一定为假,这就是著名的2-SAT问题(lrj的dfs模板)。
枚举两架飞机,假设有|Li – Ej|小于当前枚举的时间,那么两个不能同时满足,即进行加边。
每两架飞机要枚举四次,早早,早晚,晚早,晚晚。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 #include <algorithm> 5 #include <iostream> 6 using namespace std; 7 8 const int maxn = 2005; 9 10 struct twosat 11 { 12 int n; 13 vector<int> g[maxn*2]; 14 bool mark[maxn*2]; 15 int s[maxn*2],c; 16 17 bool dfs(int x) 18 { 19 if (mark[x^1]) return false; 20 if (mark[x]) return true; 21 22 mark[x] = true; 23 24 s[c++] = x; 25 26 for (int i = 0;i < g[x].size();i++) 27 { 28 if (!dfs(g[x][i])) return false; 29 } 30 31 return true; 32 } 33 34 void init(int n) 35 { 36 this -> n = n; 37 for (int i = 0;i < n * 2;i++) g[i].clear(); 38 memset(mark,0,sizeof(mark)); 39 } 40 41 void add_clause(int x,int xval,int y,int yval) 42 { 43 x = x * 2 + xval; 44 y = y * 2 + yval; 45 46 g[x^1].push_back(y); 47 g[y^1].push_back(x); 48 } 49 50 bool solve() 51 { 52 for (int i = 0;i < n * 2;i += 2) 53 { 54 if (!mark[i] && !mark[i+1]) 55 { 56 c = 0; 57 58 if (!dfs(i)) 59 { 60 while (c > 0) mark[s[--c]] = false; 61 if (!dfs(i+1)) return false; 62 } 63 } 64 } 65 66 return true; 67 } 68 } twosat; 69 70 struct node 71 { 72 int x,y; 73 74 node(int x,int y) 75 { 76 this -> x = x; 77 this -> y = y; 78 } 79 }; 80 81 vector<node> v; 82 83 int mabs(int x) 84 { 85 return x >= 0 ? x : -x; 86 } 87 88 bool meet(int k,int n) 89 { 90 twosat.init(n); 91 92 for (int i = 0;i < n;i++) 93 { 94 for (int j = i + 1;j < n;j++) 95 { 96 //if (i == j) continue; 97 if (mabs(v[i].x - v[j].x) < k) 98 { 99 twosat.add_clause(i,0,j,0); 100 } 101 if (mabs(v[i].x - v[j].y) < k) 102 { 103 twosat.add_clause(i,0,j,1); 104 } 105 if (mabs(v[i].y - v[j].y) < k) 106 { 107 twosat.add_clause(i,1,j,1); 108 } 109 if (mabs(v[i].y - v[j].x) < k) 110 { 111 twosat.add_clause(i,1,j,0); 112 } 113 } 114 } 115 116 return twosat.solve(); 117 } 118 119 120 int main() 121 { 122 int n; 123 124 while (scanf("%d",&n) != EOF) 125 { 126 v.clear(); 127 128 for (int i = 0;i < n;i++) 129 { 130 int x,y; 131 132 scanf("%d%d",&x,&y); 133 134 v.push_back(node(x,y)); 135 } 136 137 int l = 0,r = 1e7; 138 139 while (r - l > 1) 140 { 141 int mid = (l + r) >> 1; 142 143 if (meet(mid,n)) l = mid; 144 else r = mid; 145 } 146 147 while (meet(l+1,n)) l++; 148 149 printf("%d ",l); 150 } 151 152 return 0; 153 }