結果
問題 | No.2536 同値性と充足可能性 |
ユーザー |
|
提出日時 | 2023-11-10 23:25:12 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 486 ms / 2,000 ms |
コード長 | 3,412 bytes |
コンパイル時間 | 187 ms |
コンパイル使用メモリ | 82,468 KB |
実行使用メモリ | 151,424 KB |
最終ジャッジ日時 | 2024-09-26 02:21:10 |
合計ジャッジ時間 | 5,890 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 31 |
ソースコード
class UnionFind:def __init__(self, n, w=None):self.par = [-1]*nself.rank = [0]*nself.siz = [1]*nself.cnt = nself.min_node = [i for i in range(n)]self.weight = w if w else [1]*ndef root(self, x):if self.par[x] == -1:return xself.par[x] = self.root(self.par[x])return self.par[x]def issame(self, x, y):return self.root(x) == self.root(y)def unite(self, x, y):px = self.root(x)py = self.root(y)if px == py:return Falseif self.rank[px] < self.rank[py]:px, py = py, pxself.par[py] = pxif self.rank[px] == self.rank[py]:self.rank[px] += 1self.siz[px] += self.siz[py]self.cnt -= 1self.min_node[px] = min(self.min_node[px], self.min_node[py])self.weight[px] += self.weight[py]return Falsedef count(self):return self.cntdef min(self, x):return self.min_node[self.root(x)]def getweight(self, x):return self.weight[self.root(x)]def size(self, x):return self.siz[self.root(x)]import syssys.setrecursionlimit(10**6)input = sys.stdin.readlineN, M = map(int, input().split())iEj = [input().split() for _ in range(M)]UF = UnionFind(N)for i, E, j in iEj:i = int(i)j = int(j)i-=1j-=1if E=="<==>":UF.unite(i, j)D = dict()Z = []for i in range(N):r = UF.root(i)if r not in D:D[r] = len(D)Z.append(r)G = [[] for _ in range(len(D))]UF2 = UnionFind(len(D))for i, E, j in iEj:i = int(i)j = int(j)i-=1j-=1if E=="<=/=>":ri = UF.root(i)rj = UF.root(j)if ri==rj:print("No")exit()G[D[ri]].append(D[rj])G[D[rj]].append(D[ri])UF2.unite(D[ri], D[rj])color = [0] * len(D)# 頂点を1と-1で塗っていくdef dfs(v, c):color[v] = c # 頂点vをcで塗るfor i in range(len(G[v])):# 隣接している頂点が同じ色ならFalseif color[G[v][i]] == c:return False# 隣接している頂点がまだ塗られていないなら-cで塗るif color[G[v][i]] == 0 and not dfs(G[v][i], -c):return False# すべての頂点を塗れたらTruereturn Truefor i in range(len(D)):if color[i] == 0:# まだ頂点iが塗られていなければ1で塗るif not dfs(i, 1):print("No")exit()color_cnt = dict()color_group = dict()for i in range(len(D)):ri = UF2.root(i)if ri not in color_cnt:color_cnt[ri] = [0, 0]color_group[ri] = [[], []]c = color[i]if c==1:color_cnt[ri][1] += UF.size(Z[i])color_group[ri][1].append(Z[i])else:color_cnt[ri][0] += UF.size(Z[i])color_group[ri][0].append(Z[i])cnt = 0group = []for key in color_cnt:cnt0, cnt1 = color_cnt[key]if cnt0<cnt1:cnt+=cnt1group.extend(color_group[key][1])else:cnt+=cnt0group.extend(color_group[key][0])if (N+1)//2 > cnt:print("No")exit()group = set(group)ans = []for i in range(N):ri = UF.root(i)if ri in group:ans.append(i+1)print("Yes")print(len(ans))print(*ans)