zoukankan      html  css  js  c++  java
  • UVALive 3211 Now or Later (2-SAT)

    题目的要求一个最小值最大,二分即可,但是怎么判断呢?

    飞机早或者晚两种状态,可以用一个布尔变量表示,假设当前猜测为m,那么根据题意,

    如果x和y所对应的时间冲突那么就是¬(xΛy)化成或的形式(¬x)V(¬y),就可以套用twoSAT了。

    关于2-SAT,简单理解是,把逻辑推导变成一条有向边,然后跑图判断一下。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 2005;
    
    #define PB push_back
    struct TwoSAT
    {
        int n,M;
        vector<int> G[maxn*2];
        bool vis[maxn*2];
        int S[maxn*2], c;
    
        void init(int n)
        {
            this->n = n;
            M = n<<1;
            for(int i = 0; i < M; i++) G[i].clear();
            memset(vis,0,sizeof(vis));
        }
    
        bool dfs(int x)
        {
            if(vis[x^1]) return false;
            if(vis[x]) return true;
            vis[x] = true;
            S[c++] = x;
            for(int i = 0; i < (int)G[x].size(); i++){
                if(!dfs(G[x][i])) return false;
            }
            return true;
    
        }
    
        void add_clause(int x,int xv,int y,int yv)// xv or yv
        {
            x = x<<1|xv;
            y = y<<1|yv;
            G[x^1].PB(y);
            G[y^1].PB(x);
        }
    
        bool solve()
        {
            for(int i = 0; i < M; i+=2){
                if(!vis[i] && !vis[i+1]){
                    c = 0;
                    if(!dfs(i)){
                        while(c>0) vis[S[--c]] = false;
                        if(!dfs(i+1)) return false;
                    }
                }
            }
            return true;
        }
    }solver;
    
    int T[maxn][2];
    
    bool ok(int m,int n)
    {
        solver.init(n);
        for(int i = 0; i < n; i++){
            for(int xv = 0; xv < 2; xv++){
                for(int j = i+1; j < n; j++){
                    for(int yv = 0; yv < 2; yv++){
                        if(abs(T[i][xv]-T[j][yv])<m){
                            solver.add_clause(i,xv^1,j,yv^1);
                        }
                    }
                }
            }
        }
        return solver.solve();
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int n;
        while(~scanf("%d",&n)){
            int l = 0, r = 0;
            for(int i = 0; i < n; i++){
                scanf("%d%d",T[i],T[i]+1);
                r = max(r,max(T[i][0],T[i][1]));
            }
            int mid;
            for( ; l < r; ok(mid,n)?l = mid:r = mid-1) mid = (l+r+1)>>1;
            printf("%d
    ",l);
        }
        return 0;
    }
  • 相关阅读:
    jq---方法总结
    Coderfroces 862 B . Mahmoud and Ehab and the bipartiteness
    Coin
    joisino's travel
    日天的终生大事(dp)
    Codefroces 852 G. Bathroom terminal
    Codefroces432 div2 A,B,C
    Atcoder ABC 069 C
    Codefroces 849 A,B
    HDU 6186 CS Course
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4777434.html
Copyright © 2011-2022 走看看