五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

【ROSALIND】【練Python,學(xué)生信】32 構(gòu)建一棵樹(shù)

2020-01-22 17:58 作者:未琢  | 我要投稿

如果第一次閱讀本系列文檔請(qǐng)先移步閱讀【ROSALIND】【練Python,學(xué)生信】00 寫在前面 ?謝謝配合~

題目:

構(gòu)建一棵樹(shù)(Completing a Tree)

Given: A positive integer n (n≤1000) and an adjacency list corresponding to a graph on n nodes that contains no cycles.

所給:一個(gè)不大于1000的正整數(shù)n以及一個(gè)鄰接表,對(duì)應(yīng)一個(gè)有n個(gè)結(jié)點(diǎn)且無(wú)環(huán)的圖。

Return: The minimum number of edges that can be added to the graph to produce a tree.

需得:添加到圖中從而構(gòu)成樹(shù)的邊的最小數(shù)目。

?

測(cè)試數(shù)據(jù)

10

1 2

2 8

4 10

5 9

6 10

7 9

測(cè)試輸出

3

?

生物學(xué)背景

????????進(jìn)化樹(shù)是進(jìn)化生物學(xué)中用來(lái)表示物種進(jìn)化關(guān)系的圖表。從進(jìn)化樹(shù)中我們可以讀出物種間的進(jìn)化關(guān)系和距離。

?

數(shù)學(xué)背景

????????所謂無(wú)向圖就是邊沒(méi)有方向,相連兩個(gè)點(diǎn)可以互相抵達(dá)的圖。樹(shù)則是不含環(huán)的無(wú)向圖,結(jié)構(gòu)與自然界中的相對(duì)應(yīng),如下所示:

????????無(wú)向圖頂點(diǎn)的邊數(shù)稱為度(degree),度為1的結(jié)點(diǎn)為葉子結(jié)點(diǎn),度大于1的結(jié)點(diǎn)為內(nèi)節(jié)點(diǎn)。

????????鄰接表是數(shù)組與鏈表相結(jié)合的存儲(chǔ)方法。本題中所給的鄰接表每行給出的兩個(gè)數(shù)字代表兩個(gè)結(jié)點(diǎn)由邊相連。

?

思路

????????由給出的示例數(shù)據(jù)可以畫出下圖:

????????從繪圖結(jié)果很容易看出,這十個(gè)結(jié)點(diǎn)形成了四“堆”:



只需要添加三條邊就可以變成一棵樹(shù)。

????????示例所給的數(shù)據(jù)比較簡(jiǎn)單,但對(duì)復(fù)雜數(shù)據(jù),原理是相同的,請(qǐng)?jiān)斠?jiàn)代碼注釋。


代碼

f = open('input.txt', 'r')
lines = f.readlines()
f.close()

num = lines[
0] # 存儲(chǔ)結(jié)點(diǎn)的數(shù)目
edges = lines[1:] # 存儲(chǔ)邊的關(guān)系
i = 1
nodes = []
while i <= int(num):
??? nodes.append(
str(i)) # 用一個(gè)列表保存所有節(jié)點(diǎn)
???
i += 1

fedge = edges[0].replace('\n','') # 把鄰接表第一行取出來(lái),作為第一“堆”的基礎(chǔ)
fedge = fedge.split(' ')
nodes.remove(fedge[
0])
nodes.remove(fedge[
1])
tree = [fedge]
# tree用來(lái)存儲(chǔ)結(jié)點(diǎn)通過(guò)鄰接表存儲(chǔ)的關(guān)系形成的“堆”
flag = 1 # flag存儲(chǔ)現(xiàn)在tree里有幾“堆”
i = 1
while i < len(edges): # i遍歷鄰接表
???
edge = edges[i].replace('\n','')
??? edge = edge.split(
' ')
???
if edge[0] in nodes:
??????? nodes.remove(edge[
0]) # 每取出一個(gè)邊,就把形成邊的結(jié)點(diǎn)從結(jié)點(diǎn)列表中刪去
???
if edge[1] in nodes:
??????? nodes.remove(edge[
1])
??? j =
0
???
tag = 0
???
note = []
???
while j < flag: # j用來(lái)遍歷各“堆”
???????
if edge[0] in tree[j]: # 如果這條邊的一個(gè)結(jié)點(diǎn)已經(jīng)在其中一個(gè)“堆”里
???????????
tree[j].append(edge[1]) # 把這個(gè)邊加入這一“堆”
???????????
tag += 1
???????????
note.append(j) # note存儲(chǔ)這個(gè)結(jié)點(diǎn)在哪個(gè)“堆”
???????????
j += 1
???????
elif edge[1] in tree[j]:
??????????? tree[j].append(edge[
0])
??????????? tag +=
1
???????????
note.append(j)
??????????? j +=
1
???????
else: # 如果不在這一“堆”里,j加一,以查找下一“堆”
???????????
j += 1
???
if tag == 0: # 如果在之前存在的“堆”里都沒(méi)有這條邊
???????
tree.append(edge)
??????? flag +=
1 # 添加一個(gè)新的“堆”
???
if tag == 2: # 如果兩個(gè)結(jié)點(diǎn)各在兩“堆”中,說(shuō)明這兩個(gè)“堆”可以合并
???????
flag -= 1
???????
tree[note[0]].extend(tree[note[1]])
??????? tree.remove(tree[note[
1]]) # 合并兩“堆”并刪去其中一個(gè)
???????
tree[note[0]].remove(edge[0])
??????? tree[note[
0]].remove(edge[1]) # 刪去由合并導(dǎo)致的重復(fù)結(jié)點(diǎn)

???
i += 1

print(tree)
lennodes =
len(nodes) # 記錄現(xiàn)在結(jié)點(diǎn)列表中還有幾個(gè)結(jié)點(diǎn),每個(gè)都相當(dāng)于一個(gè)單獨(dú)的“堆”
sum = (flag - 1) + lennodes # “堆”的數(shù)量減去一即為需要添加的邊的數(shù)量
print(sum)

?




【ROSALIND】【練Python,學(xué)生信】32 構(gòu)建一棵樹(shù)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
云浮市| 西宁市| 延长县| 杭锦后旗| 景德镇市| 马关县| 曲靖市| 思茅市| 姚安县| 济阳县| 合水县| 铜川市| 昭觉县| 桐梓县| 临澧县| 福州市| 嘉荫县| 定襄县| 古浪县| 若尔盖县| 方城县| 射阳县| 宣化县| 略阳县| 海南省| 洮南市| 靖远县| 梅州市| 讷河市| 泸西县| 林州市| 额济纳旗| 元朗区| 曲阳县| 大庆市| 阜新市| 依安县| 拜泉县| 奉化市| 淅川县| 理塘县|