zoukankan      html  css  js  c++  java
  • POJ 3678 Katu Puzzle (2-SAT,常规)

    题意:给出n个点,每个点上有一个数字可以0或1,然后给出m条限制,要求a和b两个点上的数字满足 a op b = c,op和c都是给定。问是否能够有一组解满足所有限制?(即点上的数字是0是1由你决定)

    思路:题意很清晰了,难点在建图。要考虑所有可能的冲突:

    当op为and:  (1)c为0时,其中1个必为0。

            (2)c为1时,两者必为1。要加两条边,形如 a0->a1。

    当op为or:   (1)c为0时,两者必为0。要加两条边,形如 a1->a0。

            (2)c为1时,其中1个必为1。

    当op为xor:  (1)c为0时,两者必定相同。

            (2)c为1时,两者必定不同。

    都是按照冲突来建图就行,有没有解留给DFS去判定。

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <vector>
      5 #include <stack>
      6 #include <algorithm>
      7 #include <map>
      8 //#include <bits/stdc++.h>
      9 #define LL long long
     10 #define pii pair<int,int>
     11 #define INF 0x7f7f7f7f
     12 using namespace std;
     13 const int N=1000*2+5;
     14 int res[N][N];
     15 vector<int> vect[N*2];
     16 map<string,int> mapp;
     17 
     18 void init()
     19 {
     20     string tmp="AND";
     21     mapp[tmp]=1;
     22     tmp="OR";
     23     mapp[tmp]=2;
     24     tmp="XOR";
     25     mapp[tmp]=3;
     26 }
     27 int s[N*2], col[N*2], c;
     28 bool color(int x)
     29 {
     30     if(col[x^1])    return false;
     31     if(col[x])      return true;
     32     col[x]=2;
     33     s[c++]=x;
     34     for(int i=0; i<vect[x].size(); i++)
     35         if(!color(vect[x][i]))  return false;
     36     return true;
     37 }
     38 
     39 
     40 int cal(int n)
     41 {
     42     memset(col,0,sizeof(col));
     43     memset(s,0,sizeof(s));
     44     for(int i=0; i<n; i+=2)
     45     {
     46         if(!col[i]&&!col[i+1])
     47         {
     48             c=0;
     49             if(!color(i))
     50             {
     51                 while(c)    col[s[--c]]=0;
     52                 if(!color(i+1)) return false;
     53             }
     54         }
     55     }
     56     return true;
     57 }
     58 
     59 int main()
     60 {
     61     freopen("input.txt", "r", stdin);
     62     init();
     63     string op;
     64     int n, m, a, b, c;
     65     while(~scanf("%d%d",&n,&m))
     66     {
     67         memset(res,0xf0,sizeof(res));
     68         for(int i=n*2; i>=0; i--)   vect[i].clear();
     69 
     70         for(int i=0; i<m; i++)
     71         {
     72             scanf("%d%d%d",&a,&b,&c);
     73             cin>>op;
     74             res[a][b]=c;
     75             int t=mapp[op];
     76             //设i*2为0,i*2+1为1
     77             if(t==1)    //and
     78             {
     79                 if(c==0)    //其中必有1个为0
     80                 {
     81                     vect[a*2+1].push_back(b*2);
     82                     vect[b*2+1].push_back(a*2);
     83 
     84                 }
     85                 else        //两者必为1
     86                 {
     87                     vect[a*2].push_back(a*2+1); //指向自己
     88                     vect[b*2].push_back(b*2+1);
     89                 }
     90             }
     91             else if(t==2)   //or
     92             {
     93                 if(c==0)    //两者必为0
     94                 {
     95                     vect[a*2+1].push_back(a*2);
     96                     vect[b*2+1].push_back(b*2);
     97                 }
     98                 else        //其中必有1个为1
     99                 {
    100                     vect[a*2].push_back(b*2+1);
    101                     vect[b*2].push_back(a*2+1);
    102                 }
    103             }
    104             else        //XOR
    105             {
    106                 if(c==0)    //两者必定相同
    107                 {
    108                     vect[a*2].push_back(b*2);
    109                     vect[b*2].push_back(a*2);
    110                     vect[a*2+1].push_back(b*2+1);
    111                     vect[b*2+1].push_back(a*2+1);
    112                 }
    113                 else        //两者必定不同
    114                 {
    115                     vect[a*2].push_back(b*2+1);
    116                     vect[a*2+1].push_back(b*2);
    117                     vect[b*2].push_back(a*2+1);
    118                     vect[b*2+1].push_back(a*2);
    119                 }
    120             }
    121         }
    122         if(!cal(n<<1))    puts("NO");
    123         else    puts("YES");
    124     }
    125     return 0;
    126 }
    AC代码
  • 相关阅读:
    Exchange 2013与 Office Web Apps 整合
    SharePoint2013 以其他用户登录和修改AD域用户密码 功能
    sharepoint 2010 自定义页面布局
    sharepoint 2010 记录管理 对象模型
    SharePoint2010 对象模型 关联列表
    在SharePoint Server 2010中更改“我的网站”
    xenapp 6.5 客户端插件第一次安装总是跳到官网
    如何解决在Windows Server 2008 R2 上安装证书服务重启后出现 CertificationAuthority 91错误事件
    在Win7 Hyper-v虚拟机中挂接真实机的声卡
    win8 中如何删除 共享文件夹 用户名和密码
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4636504.html
Copyright © 2011-2022 走看看