• 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
    ",L);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    题库重整
    计算几何练习题――直线交点
    An Easy Task
    简单排序
    IBM Minus One
    Binary Numbers
    去掉VS2010代码中文注释的红色下划线
    【转】Windows socket基础
    【STL】vector的insert方法详解
    window7下 cocos2dx android交叉编译环境部署小结
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5056045.html
Copyright © 2020-2023  润新知