uvalive 3211 Now Or Later

题意:

一座飞机场要降落飞机,每架飞机有两种降落方式:早降落和晚降落。

现在要安排飞机的降落使得两个飞机降落时间的最小值最大。

输出这个最小值。

思路:

最小值最大化,可以想到答案需要二分。

然后就是如何判断一个时间是否满足条件。一个飞机要么早降落,要么晚降落,所以就是一个为真,另一个一定为假,这就是著名的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\n",l);
150     }
151     
152     return 0;
153 }

 

posted @ 2018-04-12 17:36  qrfkickit  阅读(161)  评论(0编辑  收藏  举报