題目描述無向連通圖 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個值,sum1[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...