我们可以尝试用并查集解决,并且再用一个字典来保存权重和
并查集介绍
我们这里只是用到部分并查集的知识,
def findroot(a):
while father[a]!=a:
a = father[a]
return a
#并查集-合并集合+保证根结点最小
def union_ab(a,b):
fa = findroot(a)
fb = findroot(b)
if(fa <= fb):
father[fb] = fa
else:
father[fa] = fb
#接收输入
line = input().split(" ")
n = int(line[0])
cmax = int(line[1]) #cmax是连通块的权重阈值
call = {} #记录每人的累计通话记录时长
father = {} #记录每人的父结点
for i in range(n):
line = input().split(" ") #接受每行,并用空格分开
a,b,t= line[0],line[1],int(line[2])
#累计每人的通话时长
if a not in call:
call[a] = 0
if b not in call:
call[b] = 0
call[a] += t
call[b] += t
#合并每人所在的集合
if a not in father: #若首次出现,则初始化其根结点
father[a] = a
if b not in father:
father[b] = b
union_ab(a,b)
#遍历所有人,统计它们所在的连通块
gang = {}
call['AAAA'] = 0
for key,value in father.items():
root = findroot(key)
if root not in gang:
gang[root] = [0,0,'AAAA']
gang[root][0] += call[key] #连通块权重增加
gang[root][1] += 1 #该连通块人数增加
if call[key] >= call[gang[root][2]] : #若该人权重更大,更换队首
gang[root][2] = key
#删除不合格的连通块,合并完所有连通块后,每个连通块的权重是每个人的权重总和的一半。
for key in list(gang.keys()):
if gang[key][0] <= 2*cmax :
del gang[key]
elif gang[key][1] <= 2:
del gang[key]
#对连通块排序
x = sorted(gang.items(),key = lambda x:(x[1][2])) #按队首名称升序,sort不会改变原序列,返回新序列
#按要求输出
print(len(x))
for i in x:
print(i[1][2],i[1][1])