UVaLive3211

来源:互联网 发布:网络客服工资怎么算 编辑:程序博客网 时间:2024/06/06 16:57

UVALive3211

Description

N架飞机,每架飞机有两个时间可以降落,一早一晚。

现在给出每架飞机可以降落的两个时间,问所有相邻时间降落的飞机中的最小时间间隔最大是多少。

多组测试数据。

Input

每组数据第一行:一个整数N表示飞机数。

接下来N行:每行两个整数el表示早的时间和晚的时间(别问我为什么时间长这样)。

Output

几个数据就几行:每行一个整数,最小时间间隔的最大。

solution

最小求最大,二分。

所有二分一个时间T,然后2-SAT连边:若A飞机早的那个时间A1B飞机早的那个时间B1的间隔小于T,就把A1B2连边从A1指向B2,同理也要连B1A2

code

#include<iostream>#include<string.h>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cmath>#define INF 1000000000//#include<>using namespace std;struct Fl{    int x1,x2; }F[2100];int n,R,L;struct EDGE{    int ap;    EDGE *next;}edge[21000000],*ind[2100*2];int el;int S[2100*2],sl;bool chose[2100*2];void add_edge(int x,int y){    edge[++el].ap=y;    edge[el].next=ind[x];    ind[x]=&edge[el];}void init(){    for(int i=0;i<=4100;i++) ind[i]=NULL,S[i]=0,chose[i]=0;    el=sl=0;}void build(int x){    for(int i=0;i<n;i++){        for(int j=i+1;j<n;j++){            if(abs(F[i].x1-F[j].x1)<x) add_edge(i*2,j*2+1),add_edge(j*2,i*2+1);            if(abs(F[i].x1-F[j].x2)<x) add_edge(i*2,j*2),add_edge(j*2+1,i*2+1);            if(abs(F[i].x2-F[j].x1)<x) add_edge(i*2+1,j*2+1),add_edge(j*2,i*2);            if(abs(F[i].x2-F[j].x2)<x) add_edge(i*2+1,j*2),add_edge(j*2+1,i*2);        }    }}bool dfs(int x){    bool asd=1;    if(chose[x^1]) return 0;    if(chose[x]) return 1;    chose[x]=1;    S[++sl]=x;    for(EDGE *k=ind[x];k!=NULL;k=k->next){        if(!dfs(k->ap)) asd=0;        if(asd==0)        {            return 0;        }    }    return 1;}bool check(int N){    init();    build(N);    for(int i=0;i<n;i++)    {        if(!chose[i*2+1]&&!chose[i*2])        {            sl=0;            if(!dfs(i*2+1)){                while(sl) chose[S[sl--]]=0;                if(!dfs(i*2)) return 0;            }        }    }    return 1;}int main(){    while(scanf("%d",&n)==1)    {        L=1,R=0;        for(int i=0;i<n;i++)        {            scanf("%d%d",&F[i].x1,&F[i].x2);            R=max(L,max(F[i].x1,F[i].x2));        }        R++;        while(L<R-1)        {            int mid=(L+R)/2;            if(!check(mid)) R=mid;            else L=mid;        }        printf("%d\n",L);    }    return 0;}
0 0
原创粉丝点击