zoukankan      html  css  js  c++  java
  • BZOJ2199: [Usaco2011 Jan]奶牛议会

    趁此机会学了一下2-SAT。

    以前的2-SAT都是用并查集写的,只能应用于极小的一部分情况,这次学了一正式的2-SAT,是用一张有向图来表示其依赖关系。

    2-SAT的介绍参见刘汝佳《训练指南》。

     1 /**************************************************************
     2     Problem: 2199
     3     User: zhuohan123
     4     Language: C++
     5     Result: Accepted
     6     Time:140 ms
     7     Memory:1388 kb
     8 ****************************************************************/
     9  
    10 #include <iostream>
    11 #include <cstdio>
    12 #include <cstring>
    13 #include <algorithm>
    14 using namespace std;
    15 int n,m;
    16 struct point{int y,n;}p[1100];int pnum;
    17 int head[2100];
    18 struct edge{int next,to;}g[11000];int gnum;
    19 void addedge(int from,int to)
    20 {
    21     g[++gnum].to=to;g[gnum].next=head[from];head[from]=gnum;
    22 }
    23 int q[2100],l,r;
    24 bool cango[2100];
    25 bool check(int po)
    26 {
    27     memset(cango,0,sizeof cango);
    28     cango[po]=true;l=1;r=0;q[++r]=po;
    29     while(l<=r)
    30         for(int i=head[q[l++]];i;i=g[i].next)
    31             if(!cango[g[i].to])cango[q[++r]=g[i].to]=true;
    32     for(int i=1;i<=n;i++)
    33         if(cango[p[i].y]&&cango[p[i].n])return false;
    34     return true;
    35 }
    36 char ans[1100];
    37 int main(int argc, char *argv[])
    38 {
    39     #ifndef ONLINE_JUDGE
    40         freopen("1.in","r",stdin);
    41         freopen("1.out","w",stdout);
    42     #endif
    43     scanf("%d%d",&n,&m);
    44     for(int i=1;i<=n;i++)p[i].n=++pnum,p[i].y=++pnum;
    45     while(m--)
    46     {
    47         int b,c;char vb[4],vc[4];
    48         scanf("%d%s%d%s",&b,vb,&c,vc);
    49         if(vb[0]=='Y'&&vc[0]=='Y')addedge(p[b].n,p[c].y),addedge(p[c].n,p[b].y);
    50         if(vb[0]=='Y'&&vc[0]=='N')addedge(p[b].n,p[c].n),addedge(p[c].y,p[b].y);
    51         if(vb[0]=='N'&&vc[0]=='Y')addedge(p[b].y,p[c].y),addedge(p[c].n,p[b].n);
    52         if(vb[0]=='N'&&vc[0]=='N')addedge(p[b].y,p[c].n),addedge(p[c].y,p[b].n);
    53     }
    54     for(int i=1;i<=n;i++)
    55     {
    56         bool by=check(p[i].y),bn=check(p[i].n);
    57         if(by&&bn)ans[i]='?';
    58         else if(by)ans[i]='Y';
    59         else if(bn)ans[i]='N';
    60         else {puts("IMPOSSIBLE");return 0;}
    61     }
    62     puts(ans+1);
    63     return 0;
    64 }

    P.S.这个代码写的相当非主流啊!

  • 相关阅读:
    电话号码的字母组合(力扣第17题)
    太平洋大西洋水流问题(力扣第417题)
    被围绕的区域(力扣第130题)
    ZooKeeper的本地安装和分布式安装
    朋友圈(力扣第547题)
    岛屿数量(力扣第200题)
    岛屿的最大面积(力扣第695题)
    再论力扣第279题--完全平方数
    .net core使用CSRedisCore连接哨兵集群,并用作redis使用分布式缓存。
    使用docker搭建reids主从,哨兵。
  • 原文地址:https://www.cnblogs.com/zhuohan123/p/3285261.html
Copyright © 2011-2022 走看看