UVA1146 / LA3211 (ACM-ICPC 2004 Europe-Southwestern) Now or later (2-SAT question + two-point answer)

Insert picture description here
Insert picture description here
Insert picture description here

The question is required to maximize the minimum value, which is obviously a binary answer.
Each airplane in the question is either in one state (early) or another state (late), consider 2-SAT.

We divide the answer and divide the minimum value x of the landing time interval.

Enumerate the 4 states of every two aircraft p, q

Suppose that in the enumerated case, the landing time of p is a and the landing time of q is b, then if ∣ a − b ∣ <x |ab|<xab<x then connect edges between the corresponding states (indicating that the two states can only choose one of the two, that is, asking whether the two states connected by all the edges whose interval is less than x can be satisfied at the same time).

Note that the data in this question has important edges, use vector, otherwise RE

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>

using namespace std;
typedef long long ll;
const int N = 5000007, M = 5000007, INF = 0x3f3f3f3f;

int n, m;
int dfn[N], low[N], num;
int head[N], ver[M], nex[M], tot;
vector<int>g[N];
int a[N][2];
int stk[N], top, scc_cnt;
bool ins[N];
int color[N];

void add(int x, int y){
    
    
    ver[tot] = y;
    nex[tot] = head[x];
    head[x] = tot ++ ;
}

void tarjan(int x)
{
    
    
    dfn[x] = low[x] = ++ num;
    stk[++ top] = x;
    ins[x] = true;
    for(size_t i = 0; i < g[x].size(); ++ i){
    
    
        int y = g[x][i];
        if(!dfn[y]){
    
    
            tarjan(y);
            low[x] = min(low[x], low[y]);
        }
        else if(ins[y])
            low[x] = min(low[x], dfn[y]);
    }
    if(low[x] == dfn[x]){
    
    
        int y;
        ++ scc_cnt;
        color[x] = scc_cnt;
        do{
    
    
            y = stk[top -- ];
            ins[y] = false;
            color[y] = scc_cnt;
        }while(x != y);
    }
    return ;
}

inline bool check(int x){
    
    
    //memset(head, -1, sizeof head);
    for(int i = 1; i <= 2 * n; ++ i)
        g[i].clear();
    memset(dfn, 0, sizeof dfn);
    memset(low, 0, sizeof low);
    memset(color, 0, sizeof color);
    memset(ins, 0, sizeof ins);
    tot = num = scc_cnt = 0;

    //0 : -x : E 早 : i
    //1 : x : L 晚 : i + n

    //比较之后的两个相差的时间是否小于x
    //如果小于x的话那么两者就不能同时出现(同时为true)
    for(int p = 1;p <= n;++ p){
    
    
        for(int c = 0; c <= 1; ++ c){
    
    
            for(int q = p + 1; q <= n; ++ q){
    
    
                for(int d = 0; d <= 1; ++ d){
    
    
                    if(abs(a[p][c] - a[q][d]) < x){
    
    
                        /*if(c && d){//11 -> 01, 01
                            add(p, q + n);
                            add(q, p + n);
                        }
                        else if(!c && d){//01 -> 11, 00
                            add(p + n, q + n);
                            add(q, p);
                        }
                        else if(c && !d){//10 -> 00, 11
                            add(p, q);
                            add(q + n, p + n);
                        }
                        else if(!c && !d){//00 -> 10, 01
                            add(p + n, q);
                            add(q + n, p);
                        }*/
                        g[p + n * c].push_back(q + n * (d ^ 1));
                        g[q + n * d].push_back(p + n * (c ^ 1));
                    }
                }
            }
        }
    }

    for(int i = 1; i <= 2 * n; ++ i)
        if(!dfn[i])
            tarjan(i);

    for(int i = 1; i <= n; ++ i){
    
    
        if(color[i] == color[i + n])
            return false;
    }
    return true;
}

void solve(){
    
    
    int l = 0, r = 0, ans = -1;

    for(int i =1; i <= n; ++ i)
            scanf("%d%d", &a[i][0], &a[i][1]), r = max(max(a[i][1], a[i][0]), r);


    while(l <= r){
    
    
        int mid = l + r >> 1;
        if(check(mid))ans = mid, l = mid + 1;
        else r = mid - 1;
    }
    printf("%d\n", ans);
    return ;
}

int main()
{
    
    
    while(scanf("%d", &n) != EOF){
    
    
        solve();
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45697774/article/details/108715450