Editorial for Bad Maths
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Approach
Track each variable's value relative to a representative using a weighted DSU.
Store for every node a multiplier
meaning "the value of
equals
times the value of its parent". Path compression multiplies these weights along the way. When adding
:
- If
and
are already in the same component, check whether the implied product matches
.
- Otherwise link the two roots and set the new edge weight so the equation holds.
Inconsistent equations are rejected (No) and ignored afterwards. The whole pass is nearly linear in .
Solution (Python)
class DisjointSet():
def __init__(self) -> None:
self.parent = dict[str,str]()
self.relative_to_par = dict[str,int]()
self.size = dict[str,int]()
def make_set(self, v : str) -> None:
if v not in self.parent:
self.parent[v] = v
self.size[v] = 1
self.relative_to_par[v] = 1
def find_set(self,v : str) -> tuple[str,int]:
"""
Returns: (highest parent, value relative to that parent)
"""
if (self.parent[v] == v): return (v,1)
parent,value = self.find_set(self.parent[v])
self.parent[v] = parent
self.relative_to_par[v] = value * self.relative_to_par[v]
return (self.parent[v], self.relative_to_par[v])
def new_eq(self,v : str, u : str, val : int) -> bool:
a, uval = self.find_set(v)
b, vval = self.find_set(u)
if a == b:
# Checks if current values are consistent
return uval * vval == val
val *= uval * vval
if (self.size[a] > self.size[b]):
a,b = b,a
self.parent[a] = b
self.relative_to_par[a] = val
self.size[b] += self.size[a]
return True
n = int(input())
dsu = DisjointSet()
for _ in range(n):
a,b,v = (x for x in input().split())
v = int(v)
dsu.make_set(a)
dsu.make_set(b)
print("Yes" if dsu.new_eq(a,b,v) else "No")
Comments