LA3211 Now or later

来源:互联网 发布:进口软件关税 编辑:程序博客网 时间:2024/05/16 07:50

n架飞机,每架可选择两个着落时间。安排一个着陆时间表,使得着陆间隔的最小值最大。

关键词:最小值最大:二分答案、2_sat判定

设最小值是mid,则可行解中一定没有两架飞机着陆时间差<p。若飞机着陆时间差<p,则这两个时间不能共存,转化为2_sat判定问题

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#include<vector>#include<stack>#define ll long long#define INF 0x3f3f3f3f#define maxn 2010#define tmaxn 10000010#define mem(a,b) memset(a,b,sizeof(a))using namespace std;int n,early[maxn],later[maxn],mark[maxn*2],c,S[maxn*2];vector<int> g[maxn*2];void add(int u,int v){ g[u].push_back(v); }void build(int p){    for(int i=0;i<2*n;i++) g[i].clear();    mem(mark,0);    //early---2*i later---2*i+1    for(int i=0;i<n;i++){        for(int j=i+1;j<n;j++){            if(fabs(early[i]-early[j])<p) add(2*i+1,2*j),add(2*j+1,2*i);            if(fabs(early[i]-later[j])<p) add(2*i+1,2*j+1),add(2*j,2*i);            if(fabs(later[i]-early[j])<p) add(2*i,2*j),add(2*j+1,2*i+1);            if(fabs(later[i]-later[j])<p) add(2*i,2*j+1),add(2*j,2*i+1);        }    }}bool dfs(int u){    if(mark[u]) return true;    if(mark[u^1]) return false;    mark[u]=1;S[c++]=u;    for(int i=0;i<g[u].size();i++) if(!dfs(g[u][i])) return false;    return true;}bool judge_TwoSAT(){    for(int i=0;i<2*n;i+=2){        if(!mark[i]&&!mark[i+1]){            c=0;            if(!dfs(i)){                while(c) mark[S[--c]]=false;                if(!dfs(i+1)) return false;            }        }    }    return true;}int main(){    //freopen("a.txt","r",stdin);    while(scanf("%d",&n)!=EOF){        for(int i=0;i<n;i++){            scanf("%d%d",&early[i],&later[i]);        }        int cas=0,l=0,r=tmaxn,mid;        while(l<r){            cas++;            mid=l+(r-l+1)/2;//二分小技巧:使用向上取整            build(mid);            if(judge_TwoSAT()) l=mid;            else r=mid-1;        }        printf("%d\n",l);    }    return 0;}


0 0
原创粉丝点击