标签:ace ems int tac 最小 const iostream memset ack
https://vjudge.net/problem/UVALive-3211
题意:
有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间为E,晚着陆时间为L,不得在其他时间着陆。你的任务是为这些飞机安排着陆方式,使得整个着陆计划尽量安全。换句话说,如果把所有飞机的实际着陆时间按照从早到晚的顺序排列,相邻两个着陆时间间隔的最小值。
思路:
二分查找最大值P,每次都用2—SAT判断是否可行。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 using namespace std; 11 12 const int maxn=2000+5; 13 14 int T[maxn][2]; 15 16 struct TwoSAT 17 { 18 int n; 19 vector<int> G[2*maxn]; 20 bool mark[2*maxn]; 21 int S[2*maxn],c; 22 23 bool dfs(int x) 24 { 25 if(mark[x^1]) return false; 26 if(mark[x]) return true; 27 mark[x]=true; 28 S[c++]=x; 29 for(int i=0;i<G[x].size();i++) 30 if(!dfs(G[x][i])) return false; 31 return true; 32 } 33 34 void init(int n) 35 { 36 this->n=n; 37 for(int i=0;i<2*n;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 G[x^1].push_back(y); 46 G[y^1].push_back(x); 47 } 48 49 bool solve() 50 { 51 for(int i=0;i<2*n;i+=2) 52 if(!mark[i] && !mark[i+1]) 53 { 54 c=0; 55 if(!dfs(i)) 56 { 57 while(c>0) mark[S[--c]]=false; 58 if(!dfs(i+1)) return false; 59 } 60 } 61 return true; 62 } 63 }solver; 64 65 bool test(int n,int p) 66 { 67 solver.init(n); 68 for(int i=0;i<n;i++) 69 for(int a=0;a<2;a++) 70 for(int j=i+1;j<n;j++) 71 for(int b=0;b<2;b++) 72 if(abs(T[i][a]-T[j][b])<p) solver.add_clause(i,a^1,j,b^1); 73 return solver.solve(); 74 } 75 76 int main() 77 { 78 //freopen("D:\\input.txt","r",stdin); 79 int n; 80 while(~scanf("%d",&n)) 81 { 82 int L=0,R=0; 83 for(int i=0;i<n;i++) 84 { 85 for(int a=0;a<2;a++) 86 { 87 scanf("%d",&T[i][a]); 88 R=max(R,T[i][a]); 89 } 90 } 91 while(L<=R) 92 { 93 int mid=(L+R)/2; 94 if(test(n,mid)) L=mid+1; 95 else R=mid-1; 96 } 97 printf("%d\n",R); 98 } 99 return 0; 100 }
标签:ace ems int tac 最小 const iostream memset ack
原文地址:http://www.cnblogs.com/zyb993963526/p/6803993.html