結果
問題 | No.274 The Wall |
ユーザー |
![]() |
提出日時 | 2020-11-28 19:28:58 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 187 ms / 2,000 ms |
コード長 | 3,779 bytes |
コンパイル時間 | 442 ms |
コンパイル使用メモリ | 82,252 KB |
実行使用メモリ | 78,292 KB |
最終ジャッジ日時 | 2024-09-12 23:28:02 |
合計ジャッジ時間 | 3,475 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 22 |
ソースコード
import sysinput = sys.stdin.buffer.readlinesys.setrecursionlimit(10 ** 7)class SCC_graph(object):def __init__(self, n):"""n:ノード数"""self.n = nself.edges = []def add_edge(self, frm, to):"""frm -> toへ有効辺を張る"""self.edges.append((frm, to))def __csr(self):self.start = [0] * (self.n + 1)self.elist = [0] * len(self.edges)for frm, to in self.edges:self.start[frm + 1] += 1for i in range(1, self.n + 1):self.start[i] += self.start[i - 1]cnt = self.start[:]for frm, to in self.edges:self.elist[cnt[frm]] = tocnt[frm] += 1def __dfs(self, v):self.low[v] = self.now_ordself.order[v] = self.now_ordself.now_ord += 1self.visited.append(v)for i in range(self.start[v], self.start[v + 1]):to = self.elist[i]if self.order[to] == -1:self.__dfs(to)self.low[v] = min(self.low[v], self.low[to])else:self.low[v] = min(self.low[v], self.order[to])if self.low[v] == self.order[v]:while self.visited:u = self.visited.pop()self.order[u] = self.nself.ids[u] = self.group_numif u == v:breakself.group_num += 1def _make_scc_ids(self):self.__csr()self.now_ord = 0self.group_num = 0self.visited = []self.low = [0] * self.nself.ids = [0] * self.nself.order = [-1] * self.nfor i in range(self.n):if self.order[i] == -1:self.__dfs(i)for i in range(self.n):self.ids[i] = self.group_num - 1 - self.ids[i]def scc(self):self._make_scc_ids()groups = [[] for _ in range(self.group_num)]for i in range(self.n):groups[self.ids[i]].append(i)return groupsclass TwoSAT(SCC_graph):def __init__(self, n):""" n: ノード数"""self._n = nsuper().__init__(2 * n)def add_clause(self, i, f, j, g):""" (xi == f)∨(xj == g)というクローズを追加 """x = 2 * i + (0 if f else 1)y = 2 * j + (1 if g else 0)self.add_edge(x, y)x = 2 * j + (0 if g else 1)y = 2 * i + (1 if f else 0)self.add_edge(x, y)def satisfiable(self):""" 条件を満たす割り当てが存在するか判定する """self._make_scc_ids()self._answer = [False] * self._nfor i in range(self._n):if self.ids[2 * i] == self.ids[2 * i + 1]:return Falseself._answer[i] = (self.ids[2 * i] < self.ids[2 * i + 1])return Truedef answer(self):""" 最後に読んだsatisfiableのクローズを満たす割り当てを返す """return self._answerdef intersect(a, b, c, d):if b < c or d < a:return Falsereturn Truen, m = map(int, input().split())LR = tuple(tuple(map(int, input().split())) for _ in range(n))ts = TwoSAT(n)for i, (a, b) in enumerate(LR):for j, (c, d) in enumerate(LR):if i < j:p = q = 0if intersect(a, b, c, d):ts.add_clause(i, 0, j, 0)ts.add_clause(i, 1, j, 1)p = 1if intersect(a, b, m - d - 1, m - c - 1):ts.add_clause(i, 0, j, 1)ts.add_clause(i, 1, j, 0)q = 1if p and q:print("NO")exit()if ts.satisfiable():print("YES")else:print("NO")