AcWing 240. 食物链
原题链接
中等
作者:
柠檬茶去冰
,
2024-12-13 22:41:49
,
所有人可见
,
阅读 2
import sys
#一个集合的名称,代表着是这个集合的祖宗,这个树的头,这个树的根
#diff是代表着关系!!! diff的范围在[0,2]
def find(x): #返回的是集合的名称
if p[x]!=x:
t=find(p[x]) #如果不保存一下的话
d[x]+=d[p[x]] #先p[x]=find(p[x]),就导致d[p[x]]里存的是名称的距离(0)
p[x]=t
return p[x]
n,k=map(int,input().split())
p=list(range(n+1))
d=[0]*(n+1)
res=0
for i in range(k):
op,x,y=map(int,sys.stdin.readline().split())
# 假话的条件2
if x>n or y>n:
res+=1
else:
px=find(x) #px是集合的名称
py=find(y) #py是集合的名称
#diff=0表示二者同类;diff=1表示前者吃后者;diff=2表示前者被后者
diff=(d[x]-d[y])%3
#px==py都是指要建立在用一个集合中,一开始的时候是独立的因此px!=py,
# 经过多次建立在一起一个树逐渐成型,才会有px==py,并且d[]的值也改变
if op==1:
# 假话的条件1
if px==py and diff:#diff!=0说明二者不同类,而op=1又说二者同类,说明是假话
res+=1
#进入下面语句说明要合并,要建立在同一个集合中(回扣第25行)
elif px!=py:#因此要更新集合的名称和px指向py的距离
p[px]=py#将px指向py
#因为op==1是同类,所以有px与py的距离是0,即y总33:05中左下角图((d[x]+?-d[y])%3=0)
d[px]=d[y]-d[x]#更新px指向py的距离
else:
#假话的条件3
if px==py and diff-1:#diff!=1说明前者不吃后者,而op=2又说前者吃后者,说明是假话
res+=1
#进入下面语句要合并,要建立在同一集合中(回扣第25行)
elif px!=py:
p[px]=py#将px指向py
d[px]=d[y]+1-d[x]#(前者吃后者),试着自己画图得出d[x]+?-d[y])%3=0
print(res)