zoukankan      html  css  js  c++  java
  • uva 1146 Now or late (暴力2-SAT)

    /*
    裸地2-SAT问题 关键是模型转化
    最小的最大 显然二分 关键是Judge的时候怎么判断
    每个航班是早是晚直接影响判断
    早晚只能选一个 如果我们定义bool变量xi表示 i航班是否早到
    每个航班虚拟出两个点2*i 2*i+1 分别表示是否早到 
    然后就可以假设某个航班早到然后推导出一定连得某些边 
    然后就开始选点 尝试这个点选不选 看看最后是否合法
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #define maxn 4400
    using namespace std;
    int n,l,r,g[maxn][3],f[maxn],ans,c,s[maxn];
    vector<int>G[maxn];
    int Abs(int a)
    {
        return a<0?-a:a;
    }
    void Add(int x,int y)
    {
        G[x^1].push_back(y);G[y^1].push_back(x);
    }
    bool Dfs(int x)
    {
        if(f[x^1])return 0;if(f[x])return 1;
        f[x]=1;s[c++]=x;
        for(int i=0;i<G[x].size();i++)
          if(!Dfs(G[x][i]))return 0;
        return 1;
    }
    bool Solve()//选点 
    {
        for(int i=0;i<n*2;i+=2)
          {
              if(f[i]||f[i+1])continue;c=0;//表示同一航班的两个点只选一个 
            if(!Dfs(i))
              {
                while(c>0)f[s[--c]]=0;//撤销 
                if(!Dfs(i+1))return 0;
              }
          }
        return 1;
    }
    bool Judge(int x)
    {
        for(int i=0;i<n*2;i++)G[i].clear();
        memset(f,0,sizeof(f));
        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(g[i][a]-g[j][b])<x)
            //i*2+a 不能和 j*2+b 同时选  那就i*2+a连j*2+(b^1)  j*2+b连i*2+(a^1)                                 
              Add(i*2+(a^1),j*2+(b^1));
        return Solve();
    }
    int main()
    {
        while(scanf("%d",&n)==1&&n)
          {
              l=r=ans=0;
              for(int i=0;i<n;i++)
                for(int j=0;j<2;j++)
                  {
                    scanf("%d",&g[i][j]);
                    r=max(r,g[i][j]);
                }
              while(l<=r)
                {
                    int mid=(l+r)/2;
                    if(Judge(mid))
                      {
                          ans=mid;l=mid+1;
                  }
                else r=mid-1;
              }
            printf("%d
    ",ans);
          }
        return 0;
    }
  • 相关阅读:
    微信公众号开发(二)用户关注
    搭建git服务器
    微信公众号开发(三)生成带参数的二维码
    windows 安装多个mysql
    微信公众号开发(一)前期 配置
    支付宝接口之条码支付
    mysql8.0 安装 修改密码 允许远程连接
    区块链开发金融交易平台
    区块链开发 在金融融资交易平台中的优势
    2019年区块链金融交易所钱包开发需要多少钱
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5802197.html
Copyright © 2011-2022 走看看