zoukankan      html  css  js  c++  java
  • UVA11404 Now or later

    题意:输入n个飞机的两个着陆时间,着陆时间只能两个之一,问保证安全的情况下最小可能的两个相邻时间的最小时间的最大值

    题解:最小时间最大,二分时间可不可行,两个状态表示飞机早着陆和晚着陆,时间间隔不超过mid的两个时间是不能都有的,可以用twosat

    #include <bits/stdc++.h>
    #define maxn 5100
    #define INF 0x3f3f3f3f
    typedef long long ll;
    using namespace std;
    struct TwoSAT {
        int n;
        vector<int> G[maxn*2];
        bool mark[maxn*2];
        int S[maxn*2], c;
        bool dfs(int x) {
            if (mark[x^1]) return false;
            if (mark[x]) return true;
            mark[x] = true;
            S[c++] = x;
            for (int i = 0; i < G[x].size(); i++)
                if (!dfs(G[x][i])) return false;
            return true;
        }
        void init(int n) {
            this->n = n;
            for (int i = 0; i < n*2; i++) G[i].clear();
            memset(mark, 0, sizeof(mark));
        }
        //x = xval or y = yval
        void add_clause(int x, int xval, int y, int yval) {
            x = x * 2 + xval;
            y = y * 2 + yval;
            G[x^1].push_back(y);
            G[y^1].push_back(x);
        }
        bool solve() {
        for(int i = 0; i < n*2; i += 2)
            if(!mark[i] && !mark[i+1]) {
                c = 0;
                if(!dfs(i)) {
                    while(c > 0) mark[S[--c]] = false;
                    if(!dfs(i+1)) return false;
                }
            }
        return true;
        }
    }two;
    int a[maxn], b[maxn];
    int main(){
        int n, ma = 0;
        while(~scanf("%d", &n)&&n){
            ma = 0;
            for(int i=0;i<n;i++){
                scanf("%d%d", &a[i], &b[i]);
                ma = max({ma, b[i], a[i]});
            }
            int l = 0, r = ma, ans = -1;
            while(l<=r){
                int mid = (l+r)>>1;
                two.init(n);
                for(int i=0;i<n;i++){
                    for(int j=i+1;j<n;j++){
                        if(abs(a[i]-a[j])<mid) two.add_clause(i, 0, j, 0);
                        if(abs(a[i]-b[j])<mid) two.add_clause(i, 0, j, 1);
                        if(abs(b[i]-a[j])<mid) two.add_clause(i, 1, j, 0);
                        if(abs(b[i]-b[j])<mid) two.add_clause(i, 1, j, 1);
                    }
                }
                if(two.solve()) l = mid+1, ans = mid;
                else r = mid-1;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    BZOJ 1040 (ZJOI 2008) 骑士
    BZOJ 1037 (ZJOI 2008) 生日聚会
    ZJOI 2006 物流运输 bzoj1003
    ZJOI 2006 物流运输 bzoj1003
    NOI2001 炮兵阵地 洛谷2704
    NOI2001 炮兵阵地 洛谷2704
    JLOI 2013 卡牌游戏 bzoj3191
    JLOI 2013 卡牌游戏 bzoj3191
    Noip 2012 day2t1 同余方程
    bzoj 1191 [HNOI2006]超级英雄Hero——二分图匹配
  • 原文地址:https://www.cnblogs.com/Noevon/p/7651632.html
Copyright © 2011-2022 走看看