P1268 樹的重量(思維題)

2021-09-29 15:43:35 字數 1275 閱讀 4412

題目描述

樹可以用來表示物種之間的進化關係。一棵「進化樹」是乙個帶邊權的樹,其葉節點表示乙個物種,兩個葉節點之間的距離表示兩個物種的差異。現在,乙個重要的問題是,根據物種之間的距離,重構相應的「進化樹」。

令n=,用乙個n上的矩陣m來定義樹t。其中,矩陣m滿足:對於任意的i,j,k,有m[i,j] + m[j,k] >= m[i,k]。樹t滿足:

1.葉節點屬於集合n;

2.邊權均為非負整數;

3.dt(i,j)=m[i,j],其中dt(i,j)表示樹上i到j的最短路徑長度。

如下圖,矩陣m描述了一棵樹。

樹的重量是指樹上所有邊權之和。對於任意給出的合法矩陣m,它所能表示樹的重量是惟一確定的,不可能找到兩棵不同重量的樹,它們都符合矩陣m。你的任務就是,根據給出的矩陣m,計算m所表示樹的重量。下圖是上面給出的矩陣m所能表示的一棵樹,這棵樹的總重量為15。

輸入格式

輸入資料報含若干組資料。每組資料的第一行是乙個整數n(2輸入資料以n=0結尾。

輸出格式

對於每組輸入,輸出一行,乙個整數,表示樹的重量。

輸入輸出樣例

輸入 #1複製

55 9 12 8

8 11 7

5 14

415 36 60

31 55360

輸出 #1複製

1571

思路:很有意思的思維題。很明顯,我們每次得找出最小的分枝出來。乙個點的時候是0,兩個點的時候是d(1,2),三個點的時候,第三個點是從1,2中分出來的部分,是d(1,3) - d(1,2) + d(2,3)再除以2。第四個點的時候,又是從前三個點分出來的部分,找出那個最小的分枝邊,列舉即可,列舉出來最小的就是這個分枝邊(很明顯,從點分出來的分枝邊上式計算結果是最小的)。

#include

#include

#include

using

namespace std;

const

int maxn =35;

int d[maxn]

[maxn]

;int

main()

}int ans = d[1]

[2];

for(

int i =

3;i <= n;i++

) ans +

= tmp;

}printf

("%d\n"

,ans);}

return0;

}

p1268 樹的重量

傳送門 題目 樹可以用來表示物種之間的進化關係。一棵 進化樹 是乙個帶邊權的樹,其葉節點表示乙個物種,兩個葉節點之間的距離表示兩個物種的差異。現在,乙個重要的問題是,根據物種之間的距離,重構相應的 進化樹 令n 用乙個n上的矩陣m來定義樹t。其中,矩陣m滿足 對於任意的i,j,k,有m i,j m ...

p1268樹的重量 題解

題面描述點此qwq。正解開始。一道茅塞頓開恍然大悟的題目 第一眼看到這個題的時候,語文不好的我對著題目中的 這些,和 這句話發呆半天,因為不關我怎麼構建幾何模型,我都不理解這句話。吐槽題面臃腫!然後想了一下,發現題目是這個亞子 給你乙個矩陣m,m上每乙個節點 i,j 表示葉子結點i和葉子結點j的距離...

洛谷 P1268 樹的重量

題目描述 樹可以用來表示物種之間的進化關係。一棵 進化樹 是乙個帶邊權的樹,其葉節點表示乙個物種,兩個葉節點之間的距離表示兩個物種的差異。現在,乙個重要的問題是,根據物種之間的距離,重構相應的 進化樹 令n 用乙個n上的矩陣m來定義樹t。其中,矩陣m滿足 對於任意的i,j,k,有m i,j m j,...