• POJ 2296 Map Labeler (二分+2-SAT判)


    http://poj.org/problem?id=2296

    很好的一道2-SAT题

    取上为1,取下为0

    两个新规则:

    a = 0: 这个等价于加边!a->a

    a = 1: 这个等价于加边a->!a

    当二者y差值<r时,y大的在上,y小的在下

    如果等于r时,取i xor j = 1

    如果大于r小于2r,则y大的在下,y小的在上这种情况不能存在(and = 0)

    其他情况怎么放都可以

      1 //#pragma comment(linker, "/STACK:102400000,102400000")
      2 #include<cstdio>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<string>
      6 #include<cmath>
      7 #include<set>
      8 #include<list>
      9 #include<map>
     10 #include<iterator>
     11 #include<cstdlib>
     12 #include<vector>
     13 #include<queue>
     14 #include<stack>
     15 #include<algorithm>
     16 #include<functional>
     17 using namespace std;
     18 typedef long long LL;
     19 #define ROUND(x) round(x)
     20 #define FLOOR(x) floor(x)
     21 #define CEIL(x) ceil(x)
     22 const int maxn=110;
     23 const int maxm=0;
     24 const int inf=0x3f3f3f3f;
     25 const LL inf64=0x3f3f3f3f3f3f3f3fLL;
     26 const double INF=1e30;
     27 const double eps=1e-6;
     28 
     29 /**
     30 *2-SAT模板,Modified Edition of LRJ 按字典序排列结果
     31 *输入:按照法则添加边(参数为2*i或者2*i+1)
     32 *运行:先init(n),再add(),再solve()
     33 *注意:add(2*i,2*j)才行
     34 *输出:mark[](1表示选中),solve()(是否有解)
     35 */
     36 //const int maxn = 0;
     37 struct TwoSAT
     38 {
     39     int n;
     40     vector<int> G[maxn*2];
     41     bool mark[maxn*2];
     42     int S[maxn*2], c;
     43 
     44     bool dfs(int x)
     45     {
     46         if (mark[x^1]) return false;
     47         if (mark[x]) return true;
     48         mark[x] = true;
     49         S[c++] = x;
     50         for (int i = 0; i < G[x].size(); i++)
     51             if (!dfs(G[x][i])) return false;
     52         return true;
     53     }
     54 
     55     void init(int n)
     56     {
     57         this->n = n;
     58         for (int i = 0; i < n*2; i++) G[i].clear();
     59         memset(mark, 0, sizeof(mark));
     60     }
     61 
     62     /// x AND y = 1
     63     void add_and_one(int x,int y)
     64     {
     65         G[x^1].push_back(y);
     66         G[y^1].push_back(x);
     67         G[x].push_back(y);
     68         G[y^1].push_back(x^1);
     69         G[y].push_back(x);
     70         G[x^1].push_back(y^1);
     71     }
     72 
     73     /// x AND y = 0
     74     void add_and_zero(int x,int y)
     75     {
     76         G[x].push_back(y^1);
     77         G[y].push_back(x^1);
     78     }
     79 
     80     /// x OR y = 1
     81     void add_or_one(int x,int y)
     82     {
     83         G[x^1].push_back(y);
     84         G[y^1].push_back(x);
     85     }
     86 
     87     /// x OR y = 0
     88     void add_or_zero(int x,int y)
     89     {
     90         G[x].push_back(y^1);
     91         G[y].push_back(x^1);
     92         G[x].push_back(y);
     93         G[y^1].push_back(x^1);
     94         G[x^1].push_back(y^1);
     95         G[y].push_back(x);
     96     }
     97 
     98     /// x XOR y = 1
     99     void add_xor_one(int x,int y)
    100     {
    101         G[x^1].push_back(y);
    102         G[y^1].push_back(x);
    103         G[x].push_back(y^1);
    104         G[y].push_back(x^1);
    105     }
    106 
    107     /// x XOR y = 0
    108     void add_xor_zero(int x,int y)
    109     {
    110         G[x^1].push_back(y^1);
    111         G[y].push_back(x);
    112         G[x].push_back(y);
    113         G[y^1].push_back(x^1);
    114     }
    115 
    116     /// x -> y
    117     void add_to(int x,int y)
    118     {
    119         G[x].push_back(y);
    120         G[y^1].push_back(x^1);
    121     }
    122 
    123     bool solve()
    124     {
    125         for(int i = 0; i < n*2; i += 2)
    126             if(!mark[i] && !mark[i+1])
    127             {
    128                 c = 0;
    129                 if(!dfs(i))
    130                 {
    131                     while(c > 0) mark[S[--c]] = false;
    132                     if(!dfs(i+1)) return false;
    133                 }
    134             }
    135         return true;
    136     }
    137 } sat;
    138 
    139 int n;
    140 struct Node
    141 {
    142     int x,y;
    143 } node[maxn];
    144 void init()
    145 {
    146     //
    147 }
    148 void input()
    149 {
    150     scanf("%d",&n);
    151     for(int i=0; i<n; i++) scanf("%d%d",&node[i].x,&node[i].y);
    152 }
    153 bool test(int r)
    154 {
    155     sat.init(n);
    156     for(int i=0; i<n; i++)
    157     {
    158         for(int j=i+1; j<n; j++)
    159         {
    160             if(abs(node[i].x-node[j].x)>=r||abs(node[i].y-node[j].y)>=2*r) continue;
    161             if(abs(node[i].y-node[j].y)<r)
    162             {
    163                 if(node[i].y>node[j].y)
    164                 {
    165                     sat.G[2*i+1].push_back(2*i);
    166                     sat.G[2*j].push_back(2*j+1);
    167                 }
    168                 else if(node[i].y<node[j].y)
    169                 {
    170                     sat.G[2*j+1].push_back(2*j);
    171                     sat.G[2*i].push_back(2*i+1);
    172                 }
    173                 else
    174                 {
    175                     sat.add_xor_one(2*i,2*j);
    176                 }
    177             }
    178             else
    179             {
    180                 if(node[i].y>node[j].y) sat.add_and_zero(2*i+1,2*j);
    181                 else sat.add_and_zero(2*j+1,2*i);
    182             }
    183         }
    184     }
    185     if(sat.solve()) return 1;
    186     return 0;
    187 }
    188 void solve()
    189 {
    190     int L=0,R=inf;
    191     while(L<R)
    192     {
    193         int M=L+(R-L)/2;
    194         if(!test(M)) R=M;
    195         else L=M+1;
    196     }
    197     printf("%d
    ",L-1);
    198 }
    199 void output()
    200 {
    201     //
    202 }
    203 int main()
    204 {
    205 //    std::ios_base::sync_with_stdio(false);
    206 //    freopen("in.cpp","r",stdin);
    207     int T;
    208     scanf("%d",&T);
    209     while(T--)
    210     {
    211         init();
    212         input();
    213         solve();
    214         output();
    215     }
    216     return 0;
    217 }
    View Code
  • 相关阅读:
    还原网站上被压缩的JS代码方便阅读
    让chrome浏览器变成在线编辑器
    awk之NF的妙用
    Xargs用法详解
    CU论坛常用知识点汇总
    awk中RS,ORS,FS,OFS区别与联系
    SHELL十三问[转载自CU论坛]
    关于shell中常见功能的实现方式总结
    shell实现ftp命令示例
    MySQL基础
  • 原文地址:https://www.cnblogs.com/xysmlx/p/3404018.html
Copyright © 2020-2023  润新知