日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法提高课-动态规划-树形DP-AcWing 1072. 树的最长路径:dfs写法

發布時間:2025/4/5 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法提高课-动态规划-树形DP-AcWing 1072. 树的最长路径:dfs写法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目分析

來源:acwing

分析:

樹的最長直徑:距離最遠的兩個點之間的距離,這里是帶邊權的情況。

在沒有邊權(或者邊權都是1)的時候,樹的直徑也是最遠兩個點的距離。

樣例對應的樹如下,樹的直徑= 22,對應的最長鏈是下面橘黃色的那條路徑。

經典做法:

  • 任取1點作為起點,找到距離該點最遠的點u。
  • 再找到距離u最遠的點v。
  • 這里把路徑分類,要找出路徑中最高的點。經過一個點A的所有路徑中,最高點是A點的路徑歸類到A點門下。

    這樣我們就可以枚舉所有點,找到掛到該點上的路徑的最大值即可。

    接下來的問題是:如何求掛到該點上所有路徑中的最大值(最長路徑)呢?

    這個問題的思路是:對于結點A上的所有路徑,我們找到A點的所有直接兒子,分別求它們從上往下的最大距離(到葉子結點)。我們只需要其中的最大值和次大值,記為d1和d2,則,A點的路徑長度最大值就是 d1 + d2,因為它們直接構成以A為最高點的最長路徑的長度。以下圖為例,1作為最高點,構成的最長路徑一定是從它的3個兒子中任意選擇兩個構成的。

    ac代碼

    dfs寫法

    #include<bits/stdc++.h> using namespace std; const int N = 10010, M = N * 2; int n; int h[N], e[M], ne[M], w[M], idx; int ans; // 樹的直徑存在ans中void add(int a, int b, int c){e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++; }// 以u點為最高點,返回從該點往下走的路徑的最大長度 // father防止反向遍歷,即從低到高,進入循環 int dfs(int u, int father){int dist = 0; // 從u點開始往下走的最大長度int d1 = 0, d2 = 0; //最長距離和次長距離// 遍歷所有兒子結點for(int i = h[u]; ~i; i = ne[i]){int j = e[i];// 由于是無向邊,這里防止反向搜索if(j == father) continue;int d = dfs(j,u) + w[i];dist = max(dist, d);// 如果d大于最大值d1,則最大值d1變成次大值if( d >= d1) d2 = d1, d1 = d;// 否則d如果大于次大值,則d就是次大值else if(d > d2) d2 = d;}ans = max(ans, d1 + d2);return dist; }int main(){cin >> n;memset(h, -1, sizeof h);for(int i = 0; i < n -1; i ++){int a, b, c;cin >> a >> b >> c;add(a, b, c), add(b, a ,c);}dfs(1, -1); // 任取結點作為根結點,這里選擇1號點cout << ans << endl;}

    題目來源

    https://www.acwing.com/problem/content/1074/

    總結

    以上是生活随笔為你收集整理的算法提高课-动态规划-树形DP-AcWing 1072. 树的最长路径:dfs写法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。