結果
問題 | No.274 The Wall |
ユーザー |
👑 ![]() |
提出日時 | 2021-08-24 15:38:09 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 195 ms / 2,000 ms |
コード長 | 4,684 bytes |
コンパイル時間 | 323 ms |
コンパイル使用メモリ | 82,428 KB |
実行使用メモリ | 79,052 KB |
最終ジャッジ日時 | 2024-11-14 14:32:17 |
合計ジャッジ時間 | 3,708 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 22 |
ソースコード
class Two_SAT:def __init__(self,N):""" N 変数の 2-SAT を定義する.N: int"""self.N=Nself.var_num=Nself.arc=[[] for _ in range(2*N)]self.rev=[[] for _ in range(2*N)]def var_to_index(self,v):if v>=0:return 2*velse:return 2*(-v-1)+1def index_to_var(self,i):if i%2:return -(i+1)//2else:return i//2def add_variable(self,k):""" 新たに変数 k 個を加える."""m=self.var_numself.var_num+=kself.arc+=[[] for _ in range(2*k)]self.rev+=[[] for _ in range(2*k)]return list(range(m,m+k))def __add_clause(self,i,j):self.arc[self.var_to_index(i)].append(self.var_to_index(j))self.rev[self.var_to_index(j)].append(self.var_to_index(i))def add_imply(self,i,j):""" X_i -> X_j を加える."""self.__add_clause(i,j)self.__add_clause(~j,~i)def add_or(self,i,j):""" X_i or X_j を加える."""self.add_imply(~i,j)def add_nand(self,i,j):""" not (X_i and X_j) を加える."""self.add_imply(i,~j)def add_equal(self,*I):""" I=[i_0, ..., i_{k-1}] に対して, X_{i_0}=...=X_{i_{k-1}} を追加する."""k=len(I)if k<=1:returnfor j in range(k-1):self.add_imply(I[j],I[j+1])self.add_imply(I[-1],I[0])def add_not_equal(self,i,j):""" X_i != X_j を追加する."""self.add_equal(i,~j)def set_true(self,i):""" 変数 X_i を True にする."""self.__add_clause(~i,i)def set_false(self,i):""" 変数 X_i を False にする."""self.__add_clause(i,~i)def at_most_one(self,*I):""" X_i (i in I) を満たすような i は高々1つだけという条件を追加する."""k=len(I)if k<=1:returnA=self.add_variable(k)self.add_imply(I[0],A[0])for i in range(1,k):self.add_imply(A[i-1],A[i])self.add_imply(I[i],A[i])self.add_nand(A[i-1],I[i])def is_satisfy(self,Mode=0):""" Two-SAT は充足可能?Mode:0 (Defalt): 充足可能?1: 充足可能ならば,その変数の割当を与える (不可能なときはNone).2: 充足不能の原因である変数を全て挙げる."""N=self.var_numGroup=[0]*(2*N)Order=[]for s in range(2*N):if Group[s]:continueS=[s]Group[s]=-1while S:u=S.pop()for v in self.arc[u]:if Group[v]:continueGroup[v]=-1S.append(u);S.append(v)breakelse:Order.append(u)K=0for s in Order[::-1]:if Group[s]!=-1:continueS=[s]Group[s]=Kwhile S:u=S.pop()for v in self.rev[u]:if Group[v]!=-1:continueGroup[v]=KS.append(v)K+=1if Mode==0:for i in range(N):if Group[2*i]==Group[2*i+1]:return Falsereturn Trueelif Mode==1:T=[0]*Nfor i in range(N):if Group[2*i]>Group[2*i+1]:T[i]=1elif Group[2*i]==Group[2*i+1]:return Nonereturn T[:self.N]elif Mode==2:return [i for i in range(self.N) if Group[2*i]==Group[2*i+1]]#================================================import sysinput=sys.stdin.readlineN,M=map(int,input().split())L =[0]*N;R =[0]*NIL=[0]*N;IR=[0]*Nfor i in range(N):L[i],R[i]=map(int,input().split())IL[i],IR[i]=M-1-R[i],M-1-L[i]T=Two_SAT(N)for i in range(N):for j in range(i+1,N):cnt=0if not(R[i]<L[j] or R[j]<L[i]):cnt+=1T.add_or(i,j)if not(IR[i]<L[j] or R[j]<IL[i]):cnt+=1T.add_or(~i,j)if not(R[i]<IL[j] or IR[j]<L[i]):cnt+=1T.add_or(i,~j)if not(IR[i]<IL[j] or IR[j]<IL[i]):cnt+=1T.add_or(~i,~j)if cnt==4:breakif cnt==4:breakprint("YES" if T.is_satisfy() else "NO")