• [HDOJ3622]Bomb Game


    二分+2SAT验证~

    View Code
    1 #include <cstdio>
    2 #include <cstring>
    3
    4  /*
    5
    6 * 2-SAT
    7 * 标号从1开始
    8
    9  */
    10
    11 #define OO(i) ((i & 1) ? (i + 1) : (i - 1))
    12
    13 class B_SAT
    14 {
    15 private:
    16 const static int NK = 2;
    17 const static int MAXV = 16050;
    18 const static int MAXE = 40100;
    19 const static int INF = 0x7F7F7F7F;
    20
    21 int nv;
    22
    23 int top1;
    24 int stk1[MAXV];
    25 int top2;
    26 int stk2[MAXV];
    27
    28 int times;
    29 int npart;
    30 int low[MAXV];
    31
    32 int cor[MAXV];
    33
    34 int belong[MAXV];
    35
    36 int list[MAXV];
    37 int queue[MAXV];
    38 int degree[MAXV];
    39 bool topovst[MAXV];
    40
    41 struct List
    42 {
    43 int u;
    44 int v;
    45 List * next;
    46 };
    47
    48 List pool[NK][MAXE];
    49 List * pp[NK];
    50 List * head[NK][MAXV];
    51
    52 List * create(int u,int v,List * * pp,List * next)
    53 {
    54 (*pp)->u = u;
    55 (*pp)->v = v;
    56 (*pp)->next = next;
    57 return (*pp)++;
    58 }
    59 void dfs(int v);
    60 void Gabow();
    61 void Rebuild();
    62 void Topo();
    63
    64 public:
    65 void Init(int _nv);
    66 void addEdge(int u,int v,int idx);
    67 bool solvable();
    68 void SAT();
    69 };
    70
    71 void B_SAT::dfs(int v)
    72 {
    73 low[v] = ++times;
    74 stk1[++top1] = v;
    75 stk2[++top2] = v;
    76 for (List * tp = head[0][v];tp;tp = tp->next)
    77 {
    78 int u = tp->v;
    79 if (low[u] == INF)
    80 dfs(u);
    81 else if (belong[u] == INF)
    82 while (low[stk2[top2]] > low[u])
    83 --top2;
    84 }
    85
    86 if (stk2[top2] == v)
    87 {
    88 --top2;
    89 ++npart;
    90 do
    91 {
    92 belong[stk1[top1]] = npart;
    93 }
    94 while (stk1[top1--] != v);
    95 }
    96 }
    97
    98 void B_SAT::Gabow()
    99 {
    100 top1 = top2 = times = npart = 0;
    101 memset(low,0x7F,(nv + 2) * sizeof(low[0]));
    102 memset(belong,0x7F,(nv + 2) * sizeof(belong[0]));
    103 for (int i = 1;i <= nv;i++)
    104 if (low[i] == INF)
    105 dfs(i);
    106 }
    107
    108 void B_SAT::Rebuild()
    109 {
    110 memset(degree,0,(nv + 2) * sizeof(degree[0]));
    111
    112 for (List * tp = pool[0];tp != pp[0];tp++)
    113 {
    114 int u = belong[tp->u];
    115 int v = belong[tp->v];
    116 if (u != v)
    117 {
    118 addEdge(v,u,1);
    119 degree[u]++;
    120 }
    121 }
    122 }
    123
    124 void B_SAT::Topo()
    125 {
    126 int qh = -1;
    127 int qe = -1;
    128 int cnt = 0;
    129
    130 memset(topovst,false,(nv + 2) * sizeof(topovst[0]));
    131
    132 for (int i = 1;i <= npart;i++)
    133 if (degree[i] == 0 && !topovst[i])
    134 {
    135 topovst[i] = true;
    136 list[++cnt] = i;
    137 queue[++qe] = i;
    138 while (qh != qe)
    139 {
    140 int u = queue[++qh];
    141 for (List * p = head[1][u];p;p = p->next)
    142 {
    143 degree[p->v]--;
    144 if (degree[p->v] == 0 && !topovst[p->v])
    145 {
    146 list[++cnt] = p->v;
    147 queue[++qe] = p->v;
    148 topovst[p->v] = true;
    149 }
    150 }
    151 }
    152 }
    153
    154 memset(topovst,true,(npart + 2) * sizeof(topovst[0]));
    155 for (int i = 1;i <= cnt;i++)
    156 if (topovst[list[i]])
    157 topovst[cor[list[i]]] = false;
    158 }
    159
    160 void B_SAT::Init(int _nv)
    161 {
    162 nv = _nv;
    163
    164 pp[0] = pool[0];
    165 pp[1] = pool[1];
    166 memset(head,0,sizeof(head));
    167 }
    168
    169 void B_SAT::addEdge(int u,int v,int idx)
    170 {
    171 head[idx][u] = create(u,v,&pp[idx],head[idx][u]);
    172 }
    173
    174 bool B_SAT::solvable()
    175 {
    176 Gabow();
    177 int lim = nv / 2;
    178 for (int i = 1;i <= lim;i++)
    179 {
    180 if (belong[2 * i - 1] == belong[2 * i])
    181 return false;
    182 cor[belong[2 * i - 1]] = belong[2 * i];
    183 cor[belong[2 * i]] = belong[2 * i - 1];
    184 }
    185 return true;
    186 }
    187
    188 void B_SAT::SAT()
    189 {
    190 Rebuild();
    191 Topo();
    192 for (int i = 1;i <= nv;i++)
    193 if (topovst[belong[i]])
    194 printf("%d\n",i);
    195 }
    196
    197 B_SAT sat;
    198
    199 const int SIZE = 128;
    200 const double EPS = 0.0001;
    201
    202 struct PP
    203 {
    204 int x;
    205 int y;
    206 };
    207
    208 struct LL
    209 {
    210 PP a;
    211 PP b;
    212 };
    213
    214 LL in[SIZE];
    215
    216 bool judge(const PP & a,const PP & b,double mid)
    217 {
    218 return ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)) <= 4 * mid * mid;
    219 }
    220
    221 bool isok(int nv,double mid)
    222 {
    223 sat.Init(nv << 1);
    224 for (int i = 1;i <= nv;i++)
    225 for (int j = i + 1;j <= nv;j++)
    226 {
    227 if (judge(in[i].a,in[j].a,mid))
    228 {
    229 int a = (i << 1) - 1;
    230 int b = (j << 1) - 1;
    231 sat.addEdge(a,OO(b),0);
    232 sat.addEdge(b,OO(a),0);
    233 }
    234 if (judge(in[i].a,in[j].b,mid))
    235 {
    236 int a = (i << 1) - 1;
    237 int b = (j << 1);
    238 sat.addEdge(a,OO(b),0);
    239 sat.addEdge(b,OO(a),0);
    240 }
    241 if (judge(in[i].b,in[j].a,mid))
    242 {
    243 int a = (i << 1);
    244 int b = (j << 1) - 1;
    245 sat.addEdge(a,OO(b),0);
    246 sat.addEdge(b,OO(a),0);
    247 }
    248 if (judge(in[i].b,in[j].b,mid))
    249 {
    250 int a = (i << 1);
    251 int b = (j << 1);
    252 sat.addEdge(a,OO(b),0);
    253 sat.addEdge(b,OO(a),0);
    254 }
    255 }
    256
    257 return sat.solvable();
    258 }
    259
    260
    261 int main()
    262 {
    263 int nv;
    264
    265 while (scanf("%d",&nv) != EOF)
    266 {
    267 for (int i = 1;i <= nv;i++)
    268 scanf("%d %d %d %d",&in[i].a.x,&in[i].a.y,&in[i].b.x,&in[i].b.y);
    269
    270 double high = 30000;
    271 double low = 0;
    272 double mid;
    273 double ans;
    274
    275 while (high - low > EPS)
    276 {
    277 mid = (low + high) / 2;
    278 if (isok(nv,mid))
    279 {
    280 low = mid;
    281 ans = mid;
    282 }
    283 else high = mid;
    284 }
    285
    286 printf("%.2lf\n",ans);
    287 }
    288 return 0;
    289 }
  • 相关阅读:
    selenium---元素定位(find_element)
    selenium---八种定位元素方法
    selenium---环境配置
    vue el-table 自适应表格内容宽度
    另类的开发环境搭建
    基于Django+celery二次开发动态配置定时任务 ( 二)
    基于datax的数据同步平台
    mysql常用日期、时间查询
    MySQL数据库管理
    mysql5.7.20多实例编译安装
  • 原文地址:https://www.cnblogs.com/debugcool/p/HDOJ3622.html
Copyright © 2020-2023  润新知