zoukankan      html  css  js  c++  java
  • bzoj1823

    第一道2sat,

    其实2sat问题不难,只要记住一个:通过“推导出”连边

    什么意思呢?就是一般题目中的变量都有两个状态,只能取一个,我们定义为true和false

    对于每一个变量i,我们都拆成两个点,分别表示两种状态,设2i表示true,2i+1表示false。

    然后来看每个条件,比如要满足xi=true or xj=true成立

    显然,当xj=false,我们必然能推出xi=true,所以我们就连2j+1--->2i

    同样的xi=false是,我们必然能推出xj=true,所以我们连2i+1--->2j

    根据出这样的推导出关系我们就可以构建出一个图

    如果能满足所有的条件,必然从任意变量的一个状态走,必定不能走到这个变量的对立状态

    所以我们只要tarjan一下,判断任意2i,2i+1是否在一个强联通分量中,如果不存在,就说明能满足所有条件

    这道题题目叙述很烦,只要掌握了基本的2sat问题,耐心分析一下是很容易做出的

      1 type node=record
      2        point,next:longint;
      3      end;
      4 
      5 var st,dfn,low,be,w:array[0..500] of longint;
      6     edge:array[0..200010] of node;
      7     v,f:array[0..500] of boolean;
      8     tot,l,j,len,x,y,i,h,t,n,m,sum:longint;
      9     f1,p,f2,flag:boolean;
     10     s:string;
     11 
     12 function min(a,b:longint):longint;
     13   begin
     14     if a>b then exit(b) else exit(a);
     15   end;
     16 
     17 function get(x,y:longint):longint;
     18   var i:longint;
     19   begin
     20     if s[x]='m' then p:=false else p:=true;
     21     get:=0;
     22     for i:=x+1 to y do
     23     begin
     24       if s[i]=' ' then break;
     25       get:=get*10+ord(s[i])-48;
     26     end;
     27   end;
     28 
     29 procedure add(x,y:longint);
     30   begin
     31     inc(len);
     32     edge[len].point:=y;
     33     edge[len].next:=w[x];
     34     w[x]:=len;
     35   end;
     36 
     37 procedure tarjan(x:longint);
     38   var i,y:longint;
     39   begin
     40     inc(h);
     41     dfn[x]:=h;
     42     low[x]:=h;
     43     inc(t);
     44     st[t]:=x;
     45     f[x]:=true;
     46     v[x]:=true;
     47     i:=w[x];
     48     while i<>-1 do
     49     begin
     50       y:=edge[i].point;
     51       if not v[y] then
     52       begin
     53         tarjan(y);
     54         low[x]:=min(low[x],low[y]);
     55       end
     56       else if f[y] then low[x]:=min(low[x],low[y]);
     57       i:=edge[i].next;
     58     end;
     59     if low[x]=dfn[x] then
     60     begin
     61       inc(sum);
     62       while st[t+1]<>x do
     63       begin
     64         y:=st[t];
     65         f[y]:=false;
     66         be[y]:=sum;
     67         dec(t);
     68       end;
     69     end;
     70   end;
     71 
     72 begin
     73   readln(tot);
     74   while tot>0 do
     75   begin
     76     readln(n,m);
     77     len:=0;
     78     fillchar(w,sizeof(w),255);
     79     for i:=1 to m do
     80     begin
     81       readln(s);
     82       l:=length(s);
     83       for j:=1 to l do
     84         if s[j]=' ' then break;
     85       x:=get(1,j-1);
     86       f1:=p;
     87       y:=get(j+1,l);
     88       f2:=p;
     89       if f1 and f2 then
     90       begin
     91         add(x+n,y);
     92         add(y+n,x);
     93       end
     94       else if not f1 and not f2 then
     95       begin
     96         add(x,y+n);
     97         add(y,x+n);
     98       end
     99       else if not f1 and f2 then
    100       begin
    101         add(x,y);
    102         add(y+n,x+n);
    103       end
    104       else if f1 and not f2 then
    105       begin
    106         add(x+n,y+n);
    107         add(y,x);
    108       end;
    109     end;
    110     fillchar(v,sizeof(v),false);
    111     fillchar(f,sizeof(f),false);
    112     fillchar(st,sizeof(st),0);
    113     fillchar(be,sizeof(be),0);
    114     sum:=0;
    115     for i:=1 to 2*n do
    116       if not v[i] then
    117       begin
    118         h:=0;
    119         t:=0;
    120         tarjan(i);
    121       end;
    122 
    123     flag:=true;
    124     for i:=1 to n do
    125       if be[i]=be[i+n] then
    126       begin
    127         flag:=false;
    128         break;
    129       end;
    130 
    131     if flag then writeln('GOOD') else writeln('BAD');
    132     dec(tot);
    133   end;
    134 end.
    View Code
  • 相关阅读:
    架构设计的方法学 【转】
    异常处理
    Java中---HashSet中的Set()方法不能加重复值的原因,唯一性
    java中Set集合
    java中foreach语法和总结
    泛型的处理
    迭代器错误处理
    防重复提交
    mqtt安装和使用
    字符串正则替换
  • 原文地址:https://www.cnblogs.com/phile/p/4473213.html
Copyright © 2011-2022 走看看