洛谷 1351 聯合權值

2021-09-24 11:44:33 字數 2164 閱讀 5643

題目描述

無向連通圖 g 有 n 個點,n−1 條邊。點從 1 到 n 依次編號,編號為 iii 的點的權值為 wi,每條邊的長度均為 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 的點的權值為 wi​。

輸出格式:

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

輸入輸出樣例

輸入樣例#1:

51 2

2 33 4

4 51 5 2 3 10

輸出樣例#1:

20 74

解釋:很明顯在樹上進行dp,每個點維護4個值,sum

1[ro

ot],

sum2

[roo

t],m

ax1[

root

],ma

x2[r

oot]

sum1[root],sum2[root],max1[root],max2[root]

sum1[r

oot]

,sum

2[ro

ot],

max1

[roo

t],m

ax2[

root

],分別是root孩子的權和,權平方和,最大孩子,次大孩子。那麼答案就是sum

1[ro

ot]∗

sum1

[roo

t]−s

um2[

root

],

sum1[root]*sum1[root]-sum2[root],

sum1[r

oot]

∗sum

1[ro

ot]−

sum2

[roo

t],和2∗s

um1[

son]

∗a[r

oot]

2*sum1[son]*a[root]

2∗sum1

[son

]∗a[

root

],孩子兄弟之間的貢獻,和根節點與子孫節點的貢獻,並且維護好最大值就行了,也分兩種情況,同上。

#include#define n 200004

#define mod 10007

using namespace std;

int a[n]=;

int head[n]=;

int nex[2*n]=;

int v[2*n]=;

int tot=0;

int sum1[n]=;

int sum2[n]=;

int max1[n];

int max2[n]=;

int ans=0,ret=0;

int n=0;

void add(int x,int y)

void dp(int x,int fa)else if(a[to]>max2[x])

dp(to,x);

}ret+=sum1[x]*sum1[x]-sum2[x];

ret%=mod;

ans=max(ans,max1[x]*max2[x]);

for(int i=head[x];i;i=nex[i])

}int main()

for(int i=1;i<=n;i++) cin>>a[i];

dp(1,-1);

cout

}

洛谷 1351 聯合權值

一棵樹上距離為2的兩個節點的權值相乘,問max和sum70分 列舉每個節點,它的兩個兒子必定距離為2,相加 取max即可 會t 100分 注意到,乙個節點的兒子中,互相都要乘 根據乘法分配律,我先預處理它兒子的權值和,每個節點x對聯合權值的貢獻為key x sum key x 這樣可以把o n3 的...

洛谷 1351 聯合權值

無向連通圖 gg 有 nn 個點,n 1n 1 條邊。點從 11 到 nn 依次編號,編號為 ii 的點的權值為 w iwi 每條邊的長度均為 11。圖上兩點 u,v u,v 的距離定義為 uu 點到 vv 點的最短距離。對於圖 gg 上的點對 u,v u,v 若它們的距離為 22,則它們之間會產生...

洛谷 1351 聯合權值

題解 每個點維護各個兒子的前字尾最大值 權值和,這樣就可以統計兒子之間相乘的答案。然後每個節點再乘它的祖父的權值去更新答案即可。1 include2 include3 include4 define ll long long 5 define rg register 6 define n 20001...