zoukankan      html  css  js  c++  java
  • 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
    ",L);
        }
        return 0;
    }
    

      

  • 相关阅读:
    List of the best open source software applications
    Owin对Asp.net Web的扩展
    NSwag给api加上说明
    'workspace' in VS Code
    unable to find valid certification path to requested target
    JMeter的下载以及安装使用
    exception disappear when forgot to await an async method
    Filter execute order in asp.net web api
    记录web api的request以及response(即写log)
    asp.net web api的源码
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4902598.html
Copyright © 2011-2022 走看看