码迷,mamicode.com
首页 > 其他好文 > 详细

UVAlive3211_Now or later

时间:2014-07-21 14:36:43      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   os   io   for   

白书上的例题。

每种航班可以选择两种时间降落,如果想任意航班降落时间差的最小值最大,应该如何安排?

二分时间,如果两个时间只差小于当前枚举的时间,说明这条边不可选,可以根据2sat的方法构图。

然后判断安排方案是否合法即可。

 

 

召唤代码君:

 

 

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 5555
#define maxm 26666666
using namespace std;

int to[maxm],next[maxm],first[maxn],edge;
int t[maxn],Q[maxn],top=0;
int n,m;
bool mark[maxn];

int abs(int x)
{
    return x>=0?x:-x;
}

void addedge(int U,int V)
{
    edge++;
    to[edge]=V,next[edge]=first[U],first[U]=edge;
}

bool dfs(int cur)
{
    if (mark[cur^1]) return false;
    if (mark[cur]) return true;
    Q[++top]=cur,mark[cur]=true;
    for (int i=first[cur]; i!=-1; i=next[i])
        if (!dfs(to[i])) return false;
    return true;

}

bool check(int x)
{
    edge=-1;
    for (int i=2; i<=n+n+1; i++) first[i]=-1,mark[i]=false;
    for (int i=2; i<=n+n+1; i++)
        for (int j=(i|1)+1; j<=n+n+1; j++)
            if (abs(t[i]-t[j])<x) addedge(i,j^1),addedge(j,i^1);
    for (int i=2; i<=n+n; i+=2)
    {
        if (mark[i] || mark[i+1]) continue;
        top=0;
        if (!dfs(i))
        {
            while (top) mark[Q[top--]]=false;
            if (!dfs(i+1)) return false;
        }
    }
    return true;
}

int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        for (int i=1; i<=n; i++) scanf("%d%d",&t[i+i],&t[i+i+1]);
        int l=0,r=10000000,mid;
        while (l<r)
        {
            mid=(l+r+1)>>1;
            if (check(mid)) l=mid;
                else r=mid-1;
        }
        printf("%d\n",l);
    }
    return 0;
}

UVAlive3211_Now or later,布布扣,bubuko.com

UVAlive3211_Now or later

标签:style   blog   color   os   io   for   

原文地址:http://www.cnblogs.com/Canon-CSU/p/3858145.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!