P1351 聯合權值

2022-05-01 01:03:10 字數 1802 閱讀 5387

然而這只是一道普及+/提高的大水題

洛谷鏈結

這道題是2023年提高組day1的第二題。

簡單題意就是在樹上每個點都有權值,相鄰兩點的距離為1,求距離為2的點的權值乘積的和以及最大值。

基本思路就是遍歷整棵樹,然後找到距離該點距離為2的點,計算距離,更新最大值和乘積和。

但這樣就很慢了。所以我們可以遍歷中間點,然後找到中間所連線的點,計算他們兩兩之間的乘積。

以上圖為例:

先找到節點1,遍歷與1相連的節點,有2,3,4。

計算與2距離為2的節點,有3,4。所以乘積和為dis[2]*(dis[3]+dis[4])。

計算與3距離為2的節點,有2,4。所以乘積和為dis[3]*(dis[2]+dis[4])。

計算與4距離為2的節點,有2,3。所以乘積和為dis[4]*(dis[2]+dis[3])。

這樣計算還是比較麻煩,怎麼簡化呢?

我們可以通過轉化式子來達到此目的。

dis[2]*(dis[3]+dis[4])就可以轉化成dis[2]*dis(dis[2]+dis[3]+dis[4])-dis[2]^2。

dis[3]*(dis[2]+dis[4])就可以轉化成dis[3]*dis(dis[2]+dis[3]+dis[4])-dis[3]^2。

dis[4]*(dis[2]+dis[3])就可以轉化成dis[4]*dis(dis[2]+dis[3]+dis[4])-dis[4]^2。

把他們放到一起,就是(dis[2]+dis[3]+dis[4])^2-dis[2]^2-dis[3]^2-dis[4]^2。

也就是點1連線的所有點的權值和的平方減去平方和,就可以計算出答案了。

1 #include2 #include3

#define n 1000000

4#define m 200010

5using

namespace

std;

6long

long next[n],to[n],head[m],num,j,dis[m],ans1,ans2,ans,n,a,b,mmax=-1;7

void add(long

long false_from,long

long

false_to)

12void dfs(long

long

x)22

if(dis[to[i]]>mmax1)

23 mmax1=dis[to[i]];

24else

25if(dis[to[i]]>mmax2)

26 mmax2=dis[to[i]];

27 ans1+=dis[to[i]];

28 ans2+=dis[to[i]]*dis[to[i]];29}

30if

(k)35}36

intmain()

43for(long

long i=1;i<=n;++i)

44 scanf("

%lld

",&dis[i]);

45for(long

long i=1;i<=n;++i)

46dfs(i);

47 printf("

%lld %lld

",mmax,ans);

48return0;

49 }

view code

P1351 聯合權值

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

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...