• Katu Puzzle poj 3678 kosaraju+2-SAT


    题意/Description:

      Katu Puzzle is presented as a directed graph G(VE) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c ≤ 1). One Katu is solvable if one can find each vertex Vi a value Xi (0 ≤X≤ 1) such that for each edge e(a, b) labeled by op and c, the following formula holds:

         Xa op Xb = c

      The calculating rules are:

    AND 0 1
    0 0 0
    1 0 1
    OR 0 1
    0 0 1
    1 1 1
    XOR 0 1
    0 0 1
    1 1 0

      Given a Katu Puzzle, your task is to determine whether it is solvable.

    读入/Input

      The first line contains two integers N (1 ≤ N ≤ 1000) and M,(0 ≤ M ≤ 1,000,000) indicating the number of vertices and edges.
      The following M lines contain three integers (0 ≤ a < N), b(0 ≤ b < N), c and an operator op each, describing the edges.

     

    输出/Output

      Output a line containing "YES" or "NO".

     

    题解/solution

    下面我们先把每个变量拆成两个点,一个表示值为true,一个表示值为false。然后定义连边(i,j),表示选了i必须选j。显然最后如果表示itrue和表示ifalse的两个点在同一个强连通分量,那么就无解,否则就有解。按照逆拓扑序,逐个确定对应变量的值,最终就可以得到一个可行解。

    对于本题,设i表示该变量为falsei’表示该变量为true

    and j=1---------------> add(i,i')  add(j,j')

    i and j=0---------------> add(i',j)  add(j',i)

    i or j=1 ---------------> add(i,j')  add(j',i)

    i or j=0 ---------------> add(i',i)  add(j',j)

    i xor j=1---------------> add(i',j)  add(j',i)  add(i,j') add(j,i')

    i xor j=0---------------> add(i,j)   add(i',j') add(j,i)  add(j',i')

    代码/Code

    <span style="font-family:SimSun;">const
      maxE=100001;
      maxV=1001;
    type
      arr=record
        x,y,next:longint;
      end;
    var
      n,m,cnt,nm:longint;
      f:array [0..maxE] of arr;
      v:array [0..maxV] of boolean;
      ls,order,belong:array [0..maxV] of longint;
    procedure add(o,p:longint);
    begin
      inc(nm);
      with f[nm] do
        begin
          x:=o; y:=p;
          next:=ls[o];
          ls[o]:=nm;
        end;
    end;
    
    procedure init;
    var
      i,num,x,y:longint;
      ch:char;
    begin
      fillchar(ls,sizeof(ls),0);
      nm:=0;
      readln(n,m);
      for i:=1 to m do
        begin
          read(x,y,num);
          x:=x+1; y:=y+1;
          read(ch); readln(ch);
          if ch='A' then
            if num=1 then
              begin
                add(x,x+n);
                add(y,y+n);
              end else
              begin
                add(x+n,y);
                add(y+n,x);
              end;
          if ch='O' then
            if num=1 then
              begin
                add(x,y+n);
                add(y,x+n);
              end else
              begin
                add(x+n,x);
                add(y+n,y);
              end;
          if ch='X' then
            if num=1 then
              begin
                add(x,y+n);
                add(x+n,y);
                add(y,x+n);
                add(y+n,x);
              end else
              begin
                add(x,y);
                add(y,x);
                add(x+n,y+n);
                add(y+n,x+n);
              end;
        end;
    end;
    
    procedure dfs(p,ti:longint);
    var
      t:longint;
    begin
      v[p]:=true;
      t:=ls[p];
      while t>0 do
        with f[t] do
          begin
            if not v[y] then dfs(y,ti);
            t:=next;
          end;
      if ti=0 then
        begin
          inc(cnt);
          order[cnt]:=p;
        end else belong[p]:=cnt;
    end;
    
    procedure kosaraju;
    var
      i,j,t:longint;
    begin
      fillchar(v,sizeof(v),0);
      cnt:=0;
      for i:=1 to n+n do
        if not v[i] then dfs(i,0);
      fillchar(ls,sizeof(ls),0);
      fillchar(v,sizeof(v),0);
      t:=nm; cnt:=0; nm:=0;
      for i:=1 to t do
        add(f[i].y,f[i].x);
      for i:=n+n downto 1 do
        begin
          j:=order[i];
          if not v[j] then
            begin
              inc(cnt);
              dfs(j,1);
            end;
        end;
    end;
    
    procedure print;
    var
      i:longint;
    begin
      for i:=1 to n do
        if belong[i]=belong[i+n] then
          begin
            write('NO'); halt;
          end;
      write('YES');
    end;
    
    begin
      init;
      kosaraju;
      print;
    end.
    </span>



  • 相关阅读:
    ssh实现免密码登录和文件传输
    linux后台执行程序相关命令
    orchestrator
    curl下载安装与使用
    goland使用
    mysql集群
    consul理解
    my.cnf
    数据库的表设计
    项目常见面试问题
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9319687.html
Copyright © 2020-2023  润新知