樹的最長路徑(最遠點對)


 

一、定義

  對於一棵n個結點的無根樹,找到一條最長路徑。簡單說,要找到兩個點,使得它們的距離最遠。  

 

二、求解

基本的求法是,先隨便找一個點作為根結點轉換為無根樹后,遍歷每一個點,找出當i為根結點時的子樹到葉子的最大距離d(j),在根據d(j)求出結點i作為根結點時整個樹的最長路徑,維護最長路徑即可。

  1.狀態定義:d(i),i為根結點的子樹到葉子的最大距離。
  2.狀態轉移方程:

    d(i)=max{d(j)+w(i)}

#include<stdio.h>
#include<stdlib.h>
#define FORa(i,s,e) for(int i=s;i<=e;i++)
#define FORs(i,s,e) for(int i=s;i>=e;i--)

using namespace std;
const int N=1000,INF=2147483647;
int n,num_edge,ans,head[N+1],d[N+1]; 
struct Edge{
    int next,to,dis;
}edge[2*N];
inline void Add_edge(int from,int to,int dis)
{
    edge[++num_edge]=(Edge){head[from],to,dis},head[from]=num_edge;
}
inline int max(int fa,int fb){return fa>fb?fa:fb;}

inline int Dfs(int u,int fa,int dis)
{
    int max1=0,max2=0;//子樹的鏈中的最大值與次大值 
    for(int i=head[u];i;i=edge[i].next)
    {
        if(edge[i].to!=fa) 
        {
            Dfs(edge[i].to,u,dis+edge[i].to);
            if(d[edge[i].to]+edge[i].dis>max1)
                max2=max1,max1=d[edge[i].to]+edge[i].dis;
            else if(d[edge[i].to]+edge[i].dis>max2)
                max2=d[edge[i].to]+edge[i].dis; 
        }
    }
    d[u]=max1;
    //考慮到將u作為根節點,更新子樹的鏈中的最大值與次大值 
    if(dis>max1)
        max2=max1,max1=dis;
    else if(dis>max2)
        max2=dis;
    ans=max(max1+max2,ans);
}
int main()
{
    int from,to,dis;
    scanf("%d",&n);
    FORa(i,2,n)
    {
        scanf("%d%d%d",&from,&to,&dis);
        Add_edge(from,to,dis),Add_edge(to,from,dis);
    }
    Dfs(1,0,0);
    printf("%d",ans);
    return 0;
}
/*7
1 2 4
1 3 2
2 5 1
2 6 4
3 4 9
5 7 10
*/

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM