UVALive-3211 Now or later (2-SAT+二分)

题目大意:有n架飞机,每架飞机有两个可选择的着陆时间,并且每架飞机都必须要选一个时间着陆。为了安全考虑,要求两架飞机的最小着陆时间差最大,找出这个最大值。

题目分析:有“最小值的最大值”这样的字眼,用二分。二分枚举这个最小时间差的最大值p,则问题变成了这样的:有n个只有两个元素的集合,每个元素代表一个时间点,现在要从这些集合中选出n个(一个集合中必须选出一个)元素构成新的集合,使得新集合中任意两点之间的差值都不小于p,找到满足条件的最大的p。

  如果两个不同集合中的两个元素(一个集合中一个)之间的差值(绝对值,也就是时间差)小于p,那么这两个元素之间便有矛盾,不能同时被选。例如:设x1、x2为同一个集合中的元素,y1、y2为另一个集合中的元素,如果x1与y1之差小于p,那么如果选了x1就必须选y2,反过来,选了y1就必须选x2。这样就是2-SAT模型了。只需找出使得这个2-SAT有解的最大p即可。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<vector>
# include<cstring>
# include<algorithm>
using namespace std;

const int maxn=2005;
int n,cnt,S[maxn*2],mark[maxn*2],Table[maxn][2];
vector<int>G[maxn*2];

void add(int x,int a,int y,int b)
{
    x=x*2+a;
    y=y*2+b;
    G[x^1].push_back(y);
    G[y^1].push_back(x);
}

bool dfs(int u)
{
    if(mark[u^1])   return false;
    if(mark[u]) return true;
    mark[u]=1;
    S[cnt++]=u;
    for(int i=0;i<G[u].size();++i)
        if(!dfs(G[u][i]))
            return false;
    return true;
}

bool judge(int M)
{
    for(int i=0;i<2*n;++i)  G[i].clear();
    memset(mark,0,sizeof(mark));
    for(int i=0;i<n;++i)
        for(int a=0;a<2;++a)
            for(int j=i+1;j<n;++j)
                for(int b=0;b<2;++b)
                    if(abs(Table[i][a]-Table[j][b])<M)
                        add(i,a^1,j,b^1);
    for(int i=0;i<2*n;i+=2){
        if(!mark[i]&&!mark[i+1]){
            cnt=0;
            if(!dfs(i)){
                while(cnt>0)  mark[S[--cnt]]=0;
                if(!dfs(i+1))   return false;
            }
        }
    }
    return true;
}

int main()
{
    int L,R;
    while(scanf("%d",&n)!=EOF)
    {
        L=R=0;
        for(int i=0;i<n;++i){
            scanf("%d%d",&Table[i][0],&Table[i][1]);
            R=max(R,max(Table[i][0],Table[i][1]));
        }
        while(L<R)
        {
            int M=L+(R-L+1)/2;
            if(judge(M)){
                L=M;
            }else
                R=M-1;
        }
        printf("%d\n",L);
    }
    return 0;
}

  

posted @ 2015-10-22 19:48  20143605  阅读(237)  评论(0编辑  收藏  举报