uva 11324 the largest clique (2-sat 二分答案)

来源:互联网 发布:trpg跑团软件 编辑:程序博客网 时间:2024/05/01 06:17

n架飞机,有早、晚着陆两种方式选择。让你安排着陆方式使得相邻两个着陆时间间隔的最小值尽量大。求该最大值。


建图:

每架飞机i的两个着陆时间视为两个点Ai、Ai+1

设最后答案是T,那么当对于两架飞机,若Ai-Aj <T,说明该两个着陆时间不能同时选择,选择了Ai就得选Aj+1。因此,Ai->Aj+1连一条边

二分答案,再按照上面方式建图求解即可。时间复杂度为O(n^2logT)


#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<stack>#include<vector>using namespace std;#define maxn 4005#define maxm 32000005struct Edge{    int to,next;}edge[maxm];int cnt,head[maxn],S[maxn],top;bool vis[maxn];inline void add(int u,int v){    edge[cnt].to=v;    edge[cnt].next=head[u];    head[u]=cnt++;}bool dfs(int u){    if(vis[u^1]) return 0;    if(vis[u]) return 1;    vis[u]=1;    S[top++]=u;    for(int i=head[u];~i;i=edge[i].next)        if(!dfs(edge[i].to)) return 0;    return 1;}bool solve(int n){    memset(vis,0,sizeof(vis));    for(int i=0;i<n;i+=2)    {        if(vis[i]||vis[i^1]) continue;        top=0;        if(!dfs(i))        {            while(top) vis[S[--top]]=0;            if(!dfs(i^1)) return 0;        }    }    return 1;}int n,T[maxn][2];bool test(int Time){    cnt=0;    memset(head,-1,sizeof(head));    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(T[i][a]-T[j][b])<Time){                        add(i*2+a,(2*j+b)^1);                        add(j*2+b,(2*i+a)^1);                    }    return solve(n+n);}int main(){    while(~scanf("%d",&n)&&n)    {        int L=0,R=0;        for(int i=0;i<n;++i)            for(int j=0;j<2;++j) {scanf("%d",&T[i][j]);R=max(R,T[i][j]);}        while(L<R)        {            int M=L+(R-L+1)/2;            if(test(M)) L=M;            else R=M-1;        }        printf("%d\n",L);    }    return 0;}


0 0
原创粉丝点击