• hdu1269 2-SAT问题


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269

    2-SAT问题:2-satisfiability问题(可满足性问题)也就是有n个布尔变量,给出一些不能同时存在的情况,询问是否存在满足条件的一组boolean变量的解。做法是运用原命题与逆否命题之间的等价以及同时存在的关系建有向图,对于图中的每一个SCC(强连通分量),他们中的所有的变量要么同时存在,要么同时不存在。因为对于强连通分量中的任何两个点之间都有连线,所以不存在选择某个点而不选择另一个的说法。最终我们只要判断是否存在矛盾(该矛盾不是指变量之间的限制,因为变量之间的限制已经在图中进行反映)。

    本题给出n对夫妻,还有一个会议,每对夫妻只能有一个出席,有些人不能同时出席,问是否存在一个组合使得有n个人参加会议而且没有任何矛盾。对于(A,B)之间存在矛盾我们可以知道A->B' ,还有他的逆否命题 B->A',所以要建两条边,应用对称性、tarjan+缩点、判断有没有一对夫妻在同一个SCC中便可以解决这个问题。

    代码如下:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef unsigned int ui;
      4 typedef long long ll;
      5 typedef unsigned long long ull;
      6 #define pf printf
      7 #define mem(a,b) memset(a,b,sizeof(a))
      8 #define prime1 1e9+7
      9 #define prime2 1e9+9
     10 #define pi 3.14159265
     11 #define lson l,mid,rt<<1
     12 #define rson mid+1,r,rt<<1|1
     13 #define scand(x) scanf("%llf",&x) 
     14 #define f(i,a,b) for(int i=a;i<=b;i++)
     15 #define scan(a) scanf("%d",&a)
     16 #define mp(a,b) make_pair((a),(b))
     17 #define P pair<int,int>
     18 #define dbg(args) cout<<#args<<":"<<args<<endl;
     19 #define inf 0x3f3f3f3f
     20 inline int read(){
     21     int ans=0,w=1;
     22     char ch=getchar();
     23     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
     24     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
     25     return ans*w;
     26 }
     27 const int maxn=2010;
     28 #define maxm 100010
     29 int n,m,t;
     30 int e;
     31 int head[maxn],nxt[maxm*2],dfn[maxn],low[maxn],sccno[maxn];
     32 struct node{
     33     int u,v;
     34 }p[maxm*2];
     35 void addedge(int u,int v)
     36 {
     37     p[e].u=u;
     38     p[e].v=v;
     39     nxt[e]=head[u];
     40     head[u]=e++;
     41 }
     42 stack<int> sk;
     43 int id,cnt;
     44 void tarjan(int u)//tarjan缩点 
     45 {
     46     low[u]=dfn[u]=++id;
     47     sk.push(u);
     48     for(int i=head[u];~i;i=nxt[i])
     49     {
     50         int v=p[i].v;
     51         if(!dfn[v])
     52         {
     53             tarjan(v);
     54             low[u]=min(low[u],low[v]);
     55         }
     56         else if(!sccno[v])
     57             low[u]=min(low[v],low[u]);
     58     }
     59     if(low[u]==dfn[u])
     60     {
     61         ++cnt;//cnt在循环之外标识这个SCC 
     62         while(1)
     63         {
     64             int v=sk.top();
     65             sk.pop();
     66             sccno[v]=cnt;
     67             if(u==v)break;
     68         }
     69     }
     70 }
     71 int main()
     72 {
     73     //freopen("input.txt","r",stdin);
     74     //freopen("output.txt","w",stdout);
     75     std::ios::sync_with_stdio(false);
     76     while(scanf("%d",&n)!=EOF)
     77     {
     78         m=read();
     79         int x,y,a,b,num1,num2;
     80         e=0;
     81         mem(head,-1);
     82         mem(nxt,-1);
     83         mem(dfn,0);
     84         mem(low,0);
     85         mem(sccno,0);
     86         id=0;cnt=0;
     87         while(!sk.empty())sk.pop();
     88         while(m--)
     89         {
     90             x=read(),y=read(),a=read(),b=read();//由于编号是0-n-1所以可以乘2扩展成2*n长度 
     91             num1=x*2+a;
     92             num2=y*2+b;
     93             addedge(num1,num2^1);
     94             addedge(num2,num1^1);//通过异或可以索引一对正反变量的另一个 
     95         }
     96         f(i,0,2*n-1)
     97         {
     98             if(!dfn[i])
     99             tarjan(i);
    100         }
    101         bool flag=0;
    102         f(i,0,n-1)
    103         {
    104 //            cout<<"i:"<<i<<sccno[i*2]<<":"<<sccno[2*i+1]<<endl;
    105             if(sccno[2*i]==sccno[2*i+1])//如果有一对夫妻处于同一个SCC 
    106             {
    107                 flag=1;
    108             }
    109         }
    110         if(flag)pf("NO
    ");
    111         else pf("YES
    ");
    112     } 
    113 } 
  • 相关阅读:
    idea maven 依赖还原不上的问题 method <init>()V not found
    QT6 发布程序
    Latex 公式缩放 Latex scales an equation to fit page width
    oracle使用dba账号查询死锁的表
    利用Vcpkg轻松集成开源第三方库
    python gdal 打包后运行exe Error:cannot find proj.db
    【GDAL】python读取DEM计算坡度与坡向
    docker启动关闭删除所有的容器命令
    用命令行编译libjpeg.lib
    mysql外键说明
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12589026.html
Copyright © 2020-2023  润新知