UVAlive3211 Now or later(2-SAT)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33799
【思路】
2-SAT。
二分安全间隔x,先到为1后到为0,则唯一的限制即两个不同的时间a b如果其间隔小于x则不能满足(a=1 and b=1),即满足 (a or b)=1,如果满足所有的约束条件则x可行。
时间复杂度为O(logt*n^2)。
【代码】
1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 9 const int maxn = 2000+10; 10 11 struct TwoSAT { 12 int n; 13 vector<int> G[maxn*2]; 14 bool mark[maxn*2]; 15 int S[maxn*2],c; 16 17 void init(int n) { 18 this->n=n; 19 for(int i=0;i<n*2;i++) G[i].clear(); 20 memset(mark,0,sizeof(mark)); 21 } 22 void addc(int x,int xval,int y,int yval) { 23 x=x*2+xval; 24 y=y*2+yval; 25 G[x^1].push_back(y); 26 G[y^1].push_back(x); 27 } 28 bool dfs(int x) { 29 if(mark[x^1]) return false; 30 if(mark[x]) return true; 31 mark[x]=true; 32 S[c++]=x; 33 for(int i=0;i<G[x].size();i++) 34 if(!dfs(G[x][i])) return false; 35 return true; 36 } 37 bool solve() { 38 for(int i=0;i<n*2;i+=2) 39 if(!mark[i] && !mark[i+1]) { 40 c=0; 41 if(!dfs(i)) { 42 while(c>0) mark[S[--c]]=false; 43 if(!dfs(i+1)) return false; 44 } 45 } 46 return true; 47 } 48 }ts; 49 50 int n; 51 int t[maxn][2]; 52 53 bool can(int M) { 54 ts.init(n); 55 for(int i=0;i<n;i++) for(int a=0;a<2;a++) 56 for(int j=i+1;j<n;j++) for(int b=0;b<2;b++) 57 if(abs(t[i][a]-t[j][b])<M) ts.addc(i,a^1,j,b^1); 58 return ts.solve(); 59 } 60 61 int main() { 62 while(scanf("%d",&n)==1) { 63 int L=0,R=0; 64 for(int i=0;i<n;i++) { 65 scanf("%d%d",&t[i][0],&t[i][1]); 66 R=max(R,t[i][1]); 67 } 68 while(L<R) { 69 int M=L+(R-L+1)/2; 70 if(can(M)) L=M; else R=M-1; 71 } 72 printf("%d\n",L); 73 } 74 return 0; 75 }
posted on 2015-12-18 09:04 hahalidaxin 阅读(166) 评论(0) 编辑 收藏 举报