1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| ''' 按秩归并 是对union方法的改进。
路径压缩是对find方法改进。
'''
def find(x,s): if s[x] < 0: return x else: s[x] = find(s[x], s) return s[x]
''' 引理Targan 令T(M,N)为交错执行 M>=N 次带路径压缩的查找,和 N-1 次按秩归并的最坏情况时间。 则 存在常数 k1 k2 使得: k1 * M * a(M,N) <= T(M,N) <= k2 * M * a(M,N)
a(M,N) = min{i>=1, A(i,\M/N\)>log N } <= O(log* N) <= 4
''' def find(x,s): if s[x] < 0: return x else: s[x] = find(s[x], s) return s[x]
def union(x,y,s): if abs(s[x]) < abs(s[y]): s[y] += s[x] s[x] = y print('1 !', s[x], s[y]) elif abs(s[x]) > abs(s[y]): s[x] += s[y] s[y] = x elif abs(s[x]) == abs(s[y]): s[y] += s[x] s[x] = y
def main(L): S = L.pop(0)[0] * [-1] for o in L: print(o,o[0]) if o[0] == 'i': Input_connection(o[1],o[2],S) if o[0] == 'c': Check_connection(o[1],o[2],S) if o[0] == 's': Check_network(S)
def Input_connection(node1,node2,S): root1 = find(node1-1,S) root2 = find(node2-1,S) if root1 != root2: union(root1,root2,S) def Check_connection(node1,node2,S): root1 = find(node1-1,S) root2 = find(node2-1,S) if root1 == root2: print('yes') else: print('no') def Check_network(S): num = 0 for i in range(len(S)): if S[i] < 0: num += 1 if num == 1: print('the network is connected') else: print('there are %d components.'%num)
if __name__ == '__main__': L = [[5] , ['c', 3, 2] , ['i', 3, 2], ['c', 3, 2] , ['i', 4, 5], ['i', 2, 4], ['c', 3, 5], ['i', 1, 3], ['c', 1, 5], ['s'] ]
main(L)
|