zoukankan      html  css  js  c++  java
  • 2-sat

    study from:

    https://www.cnblogs.com/-ZZB-/p/6635483.html

    条件1~条件n true 或 false (互反状态)

    若干对  (not)条件x -> (not)条件y

    https://www.luogu.org/problemnew/show/P4782

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <time.h>
      6 #include <string>
      7 #include <set>
      8 #include <map>
      9 #include <list>
     10 #include <stack>
     11 #include <queue>
     12 #include <vector>
     13 #include <bitset>
     14 #include <ext/rope>
     15 #include <algorithm>
     16 #include <iostream>
     17 using namespace std;
     18 #define ll long long
     19 #define minv 1e-6
     20 #define inf 1e9
     21 #define pi 3.1415926536
     22 #define nl 2.7182818284
     23 const ll mod=1e9+7;//998244353
     24 const int maxn=2e6+10;
     25 
     26 vector<int>e[maxn];
     27 bool vis[maxn]={0},ins[maxn]={0};
     28 int num=0,g=0,_index=0;
     29 int dfn[maxn],low[maxn],st[maxn],tag[maxn];
     30 
     31 void tarjan(int d)
     32 {
     33     vector<int>::iterator i;
     34     int dd;
     35     dfn[d]=low[d]=++num;
     36     st[++g]=d;
     37     vis[d]=1;
     38     for (i=e[d].begin();i!=e[d].end();i++)
     39     {
     40         dd=*i;
     41         if (!vis[dd])
     42         {
     43             tarjan(dd);
     44             low[d]=min(low[d],low[dd]);
     45         }
     46         else if (!ins[dd])
     47             low[d]=min(low[d],dfn[dd]);
     48     }
     49     if (dfn[d]==low[d])
     50     {
     51         _index++;
     52         while (st[g]!=d)
     53         {
     54             tag[st[g]]=_index;
     55             ins[st[g]]=1;
     56             g--;
     57         }
     58         tag[st[g]]=_index;
     59         ins[st[g]]=1;
     60         g--;
     61     }
     62 }
     63 
     64 int main()
     65 {
     66     int n,m,a,b,i,j;
     67     scanf("%d%d",&n,&m);
     68     while (m--)
     69     {
     70         scanf("%d%d%d%d",&a,&i,&b,&j);
     71         if (i==1 && j==1)
     72         {
     73             e[a+n].push_back(b);
     74             e[b+n].push_back(a);
     75         }
     76         else if (i==1 && j==0)
     77         {
     78             e[a+n].push_back(b+n);
     79             e[b].push_back(a);
     80         }
     81         else if (i==0 && j==1)
     82         {
     83             e[a].push_back(b);
     84             e[b+n].push_back(a+n);
     85         }
     86         else
     87         {
     88             e[a].push_back(b+n);
     89             e[b].push_back(a+n);
     90         }
     91     }
     92     for (i=1;i<=(n<<1);i++)
     93         if (!vis[i])
     94             tarjan(i);
     95     for (i=1;i<=n;i++)
     96         if (tag[i]==tag[i+n])
     97         {
     98             printf("IMPOSSIBLE");
     99             return 0;
    100         }
    101     printf("POSSIBLE
    ");
    102     for (i=1;i<=n;i++)
    103     {
    104         printf("%d",tag[i]<tag[i+n]);
    105         if (i!=n)
    106             printf(" ");
    107     }
    108     return 0;
    109 }

     

    题目:

    1.

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

    选择头部 与 选择尾部 为互反状态

    两条线段:一条线段的a不能与另一条线段的b以一起,则a->反b , b->反a

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <time.h>
      6 #include <string>
      7 #include <set>
      8 #include <map>
      9 #include <list>
     10 #include <stack>
     11 #include <queue>
     12 #include <vector>
     13 #include <bitset>
     14 #include <ext/rope>
     15 #include <algorithm>
     16 #include <iostream>
     17 using namespace std;
     18 #define ll long long
     19 #define minv 1e-6
     20 #define inf 1e9
     21 #define pi 3.1415926536
     22 #define nl 2.7182818284
     23 const ll mod=1e9+7;//998244353
     24 const int maxn=2e3+10;
     25 
     26 vector<int>e[maxn];
     27 bool vis[maxn]={0},ins[maxn]={0};
     28 int dfn[maxn],low[maxn],st[maxn],tag[maxn];
     29 int num=0,g=0,tot=0;
     30 int s[maxn],t[maxn],l[maxn];
     31 
     32 void tarjan(int d)
     33 {
     34     int dd;
     35     vector<int>::iterator i;
     36     vis[d]=1;
     37     dfn[d]=low[d]=++num;
     38     st[++g]=d;
     39     for (i=e[d].begin();i!=e[d].end();i++)
     40     {
     41         dd=*i;
     42         if (!vis[dd])
     43         {
     44             tarjan(dd);
     45             low[d]=min(low[d],low[dd]);
     46         }
     47         else if (!ins[dd])
     48             low[d]=min(low[d],dfn[dd]);
     49     }
     50     if (dfn[d]==low[d])
     51     {
     52         tot++;
     53         while (st[g]!=d)
     54         {
     55             tag[st[g]]=tot;
     56             ins[st[g]]=1;
     57             g--;
     58         }
     59         tag[st[g]]=tot;
     60         ins[st[g]]=1;
     61         g--;
     62     }
     63 }
     64 
     65 bool inter(int a,int b,int c,int d)
     66 {
     67     if (b<=c || d<=a)
     68         return 0;
     69     else
     70         return 1;
     71 }
     72 
     73 
     74 int main()
     75 {
     76     int n,i,j,s1,s2,t1,t2;
     77     scanf("%d",&n);
     78     for (i=1;i<=n;i++)
     79     {
     80         scanf("%d:%d %d:%d %d",&s1,&s2,&t1,&t2,&l[i]);
     81         s[i]=s1*60+s2;
     82         t[i]=t1*60+t2;
     83         if (t[i]-s[i]<l[i])
     84         {
     85             printf("NO
    ");
     86             return 0;
     87         }
     88     }
     89 
     90     for (i=1;i<=n;i++)
     91         for (j=i+1;j<=n;j++)
     92         {
     93             if (inter(s[i],s[i]+l[i],s[j],s[j]+l[j]))
     94             {
     95                 e[i].push_back(j+n);
     96                 e[j].push_back(i+n);
     97             }
     98             if (inter(s[i],s[i]+l[i],t[j]-l[j],t[j]))
     99             {
    100                 e[i].push_back(j);
    101                 e[j+n].push_back(i+n);
    102             }
    103             if (inter(t[i]-l[i],t[i],s[j],s[j]+l[j]))
    104             {
    105                 e[i+n].push_back(j+n);
    106                 e[j].push_back(i);
    107             }
    108             if (inter(t[i]-l[i],t[i],t[j]-l[j],t[j]))
    109             {
    110                 e[i+n].push_back(j);
    111                 e[j+n].push_back(i);
    112             }
    113         }
    114     for (i=1;i<=(n<<1);i++)
    115         if (!vis[i])
    116             tarjan(i);
    117     for (i=1;i<=n;i++)
    118         if (tag[i]==tag[i+n])
    119         {
    120             printf("NO");
    121             return 0;
    122         }
    123     printf("YES
    ");
    124     for (i=1;i<=n;i++)
    125     {
    126         if (tag[i]<tag[i+n])
    127             printf("%02d:%02d %02d:%02d
    ",s[i]/60,s[i]%60,(s[i]+l[i])/60,(s[i]+l[i])%60);
    128         else
    129             printf("%02d:%02d %02d:%02d
    ",(t[i]-l[i])/60,(t[i]-l[i])%60,t[i]/60,t[i]%60);
    130     }
    131     return 0;
    132 }

    2.

    https://www.luogu.org/problemnew/show/P1776

    a题选择1锦囊和a题选择2锦囊为互反状态

    若a题和b题都选择1锦囊,则a题选择1锦囊->b题选择除1锦囊外的另外一个锦囊

    3.

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

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <time.h>
      6 #include <string>
      7 #include <set>
      8 #include <map>
      9 #include <list>
     10 #include <stack>
     11 #include <queue>
     12 #include <vector>
     13 #include <bitset>
     14 #include <ext/rope>
     15 #include <algorithm>
     16 #include <iostream>
     17 using namespace std;
     18 #define ll long long
     19 #define minv 1e-6
     20 #define inf 1e9
     21 #define pi 3.1415926536
     22 #define nl 2.7182818284
     23 const ll mod=1e9+7;//998244353
     24 const int maxn=2e3+10;
     25 
     26 vector<int>e[maxn];
     27 bool vis[maxn]={0},ins[maxn]={0};
     28 int dfn[maxn],low[maxn],st[maxn],tag[maxn];
     29 int num=0,g=0,tot=0;
     30 
     31 void tarjan(int d)
     32 {
     33     int dd;
     34     vector<int>::iterator i;
     35     vis[d]=1;
     36     dfn[d]=low[d]=++num;
     37     st[++g]=d;
     38     for (i=e[d].begin();i!=e[d].end();i++)
     39     {
     40         dd=*i;
     41         if (!vis[dd])
     42         {
     43             tarjan(dd);
     44             low[d]=min(low[d],low[dd]);
     45         }
     46         else if (!ins[dd])
     47             low[d]=min(low[d],dfn[dd]);
     48     }
     49     if (dfn[d]==low[d])
     50     {
     51         tot++;
     52         while (st[g]!=d)
     53         {
     54             tag[st[g]]=tot;
     55             ins[st[g]]=1;
     56             g--;
     57         }
     58         tag[st[g]]=tot;
     59         ins[st[g]]=1;
     60         g--;
     61     }
     62 }
     63 
     64 bool inter(int a,int b,int c,int d)
     65 {
     66     if (b<=c || d<=a)
     67         return 0;
     68     else
     69         return 1;
     70 }
     71 
     72 
     73 int main()
     74 {
     75     int n,m,i,a,b,c;
     76     char d[5];
     77     scanf("%d%d",&n,&m);
     78     while (m--)
     79     {
     80         scanf("%d%d%d%s",&a,&b,&c,d);
     81         if (d[0]=='A')
     82         {
     83             if (c==1)
     84             {
     85                 e[a].push_back(b);
     86                 e[b].push_back(a);
     87 
     88                 e[a+n].push_back(b);
     89                 e[a+n].push_back(b+n);
     90 
     91                 e[b+n].push_back(a);
     92                 e[b+n].push_back(a+n);
     93             }
     94             else
     95             {
     96                 e[a].push_back(b+n);
     97                 e[b].push_back(a+n);
     98             }
     99         }
    100         else if (d[0]=='O')
    101         {
    102             if (c==1)
    103             {
    104                 e[a+n].push_back(b);
    105                 e[b+n].push_back(a);
    106             }
    107             else
    108             {
    109                 e[a+n].push_back(b+n);
    110                 e[b+n].push_back(a+n);
    111 
    112                 e[a].push_back(b);
    113                 e[a].push_back(b+n);
    114 
    115                 e[b].push_back(a);
    116                 e[b].push_back(a+n);
    117             }
    118         }
    119         else if (d[0]=='X')
    120         {
    121             if (c==1)
    122             {
    123                 e[a].push_back(b+n);
    124                 e[b].push_back(a+n);
    125             }
    126             else
    127             {
    128                 e[a].push_back(b);
    129                 e[b].push_back(a);
    130             }
    131         }
    132     }
    133 
    134     for (i=1;i<=(n<<1);i++)
    135         if (!vis[i])
    136             tarjan(i);
    137     for (i=1;i<=n;i++)
    138         if (tag[i]==tag[i+n])
    139         {
    140             printf("NO");
    141             return 0;
    142         }
    143     printf("YES");
    144     return 0;
    145 }
  • 相关阅读:
    请说出这些测试最好由那些人员完成,测试的是什么?
    测试结束的标准是什么?
    你的测试职业发展目标是什么?
    elementui医疗
    医疗前端
    spring创建对象3种方式
    idea-git
    eclipse-git
    ArrayList01
    单体权限
  • 原文地址:https://www.cnblogs.com/cmyg/p/9557399.html
Copyright © 2011-2022 走看看