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;
    }
  • 相关阅读:
    题解 SP27102/UVA1747 【Swap Space】
    题解 P1453 【城市环路】
    题解 P5587 【打字练习】
    题解 P5594 【【XR-4】模拟赛】
    git add 的一点说明
    理解 Git 的基本概念 ( Merging Collaborating Rebasing)
    windows 上 Python 通过 SCP 连接linux server
    Neo4j CQL | WITH用法
    Neo4j CQL |create &merge
    Item 4: Prefer Interpolated F-Strings Over C-style Format Strings and str.format(请使用f-string格式化字符串)
  • 原文地址:https://www.cnblogs.com/Noevon/p/7651632.html
Copyright © 2011-2022 走看看