PAT 甲级 1034 Head of a Gang (并查集)——python

我们可以尝试用并查集解决,并且再用一个字典来保存权重和
并查集介绍
我们这里只是用到部分并查集的知识,

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])
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leosaf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值