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\n", ans);
    }
    return 0;
}

 

posted on 2017-10-11 17:11  2855669158  阅读(112)  评论(0编辑  收藏  举报

导航