P1351 聯合權值

2022-03-23 03:04:01 字數 1724 閱讀 3445

無向連通圖g有n個點,n-1 條邊。點從1到n依次編號,編號為i的點的權值為w_i

,每條邊的長度均為 1。圖上兩點(u,v) 的距離定義為 u 點到 v 點的最短距離。對於圖 g 上的點對 (u,v),若它們的距離為 2,則它們之間會產生wv*wu的聯合權值。

請問圖 g上所有可產生聯合權值的有序點對中,聯合權值最大的是多少?所有聯合權值之和是多少?

輸入格式:

第一行包含 1個整數 n。

接下來 n-1 行,每行包含 2個用空格隔開的正整數 u,v表示編號為 u 和編號為 v 的點之間有邊相連。

最後 1 行,包含 n 個正整數,每兩個正整數之間用乙個空格隔開,其中第 i 個整數表示圖 g 上編號為 i 的點的權值為 w_i。

輸出格式:

輸出共 1 行,包含 2 個整數,之間用乙個空格隔開,依次為圖 g 上聯合權值的最大值和所有聯合權值之和。由於所有聯合權值之和可能很大,輸出它時要對10007取餘。

輸入樣例#1:

5 1 2

2 33 4

4 5

1 5 2 3 10

輸出樣例#1:

本例輸入的圖如上所示,距離為2 的有序點對有(1,3) 、(2,4) 、(3,1) 、 (3,5)、(4,2) 、(5,3)。

其聯合權值分別為2 、15、2 、20、15、20。其中最大的是20,總和為74。

【資料說明】

對於30%的資料,1

對於60%的資料,1

對於100%的資料,1

保證一定存在可產生聯合權值的有序點對。

5年前的d1t2我調了3天沒調出來,orz了一堆大佬才懂???

根據題目給的條件可知這是一顆樹,目標就是說去求所有距離為2的點權值之積的和與最大值,第一想法是去列舉每個節點,找出所有與它距離為2的點,但是很明顯會超時,只能得到70分,究其原因則是因為無向邊要計算兩遍,順著這個思路走,會想到去組合邊,之後整體×2即可,於是想到要去列舉中間的轉折點(其實一開始就應該想到,因為故意要求距離為2的點),這個過程實際上還是乙個乘法分配律的應用,當前的點要和之前的點乙個乙個乘,不必去列舉其它點,只需記錄它們的和,有點類似於字首和的思想,但實際上是乙個乘法分配律的應用。而以當前節點作為中轉點的最大聯合權值,肯定是最大數乘上次大數,在這裡不用記錄次大數,只需線性掃一遍打一遍擂台即可

1 #include2 #include3 #include4

using

namespace

std;

5long

long n,x,y,v[500001],head[500001],nxt[500001],cnt,w[200001];6

long

long

sum,maxx;

7void add(int a,int b)//

鏈式前向星存邊,效率高,在圖論中有很重要的作用 813

intmain()

1422

for(int i=1;i<=n;i++)scanf("

%lld

",&w[i]);

23for(int i=1;i<=n;i++)

2433

}34 cout

"<2%10007;35

return0;

36 }

view code

P1351 聯合權值

然而這只是一道普及 提高的大水題 洛谷鏈結 這道題是2014年提高組day1的第二題。簡單題意就是在樹上每個點都有權值,相鄰兩點的距離為1,求距離為2的點的權值乘積的和以及最大值。基本思路就是遍歷整棵樹,然後找到距離該點距離為2的點,計算距離,更新最大值和乘積和。但這樣就很慢了。所以我們可以遍歷中間...

P1351 聯合權值

為了寫一寫lca,我就按照標籤找 結果這道題我寫完竟然沒用lca 真是神奇。很多人 包括我 首先就想到了要列舉每乙個點,再列舉任意這個點的兩個兒子,可是顯然o n2 會t 其實我們只要線性掃一遍就可以了,利用小學學到的乘法分配率,邊走邊加val,這樣下乙個點和val的乘積就是它和這之前所有的點的乘積...

P1351 聯合權值

題意 無向連通圖 g 有 n 個點,n 1 條邊。點從 1 到 n 依次編號,編號為 i 的點的權值為 w i 每條邊的長度均為 1。圖上兩點 u,v 的距離定義為 u 點到 v 點的最短距離。對於圖 g 上的點對 u,v 若它們的距離為 2,則它們之間會產生 w v w u 的聯合權值。請問圖 g...