樹(shù)的直徑

地點(diǎn)

解釋 :
求樹(shù)的最長(zhǎng)路(樹(shù)的直徑)
首先假設(shè)樹(shù)的最長(zhǎng)路的兩個(gè)葉子節(jié)點(diǎn)為v1,v2,那么現(xiàn)有結(jié)論,從任意一點(diǎn)u出發(fā)走到的最遠(yuǎn)的點(diǎn)一定是(v1,v2)中的一點(diǎn),然后
再?gòu)膙1或者v2出發(fā)走到的最遠(yuǎn)點(diǎn)一定是v2或者v1。所以經(jīng)過(guò)兩次搜索就能找到最長(zhǎng)路徑.

相關(guān)證明
AC代碼:
dfs 找節(jié)點(diǎn)

#include<cstdio>
#include<vector>
#include<cstring>
#define CLR(x) memset(x,0,sizeof(x))
using namespace std;
const int maxn=1e5+5;
int dep[maxn];
int max_len,root,n;
int vis[maxn];
vector<int>ve[maxn];
int dfs(int x,int len)
{
    vis[x]=1;
    if(len >max_len) max_len=len,root=x;
    for(int i=0;i<ve[x].size();i++){
        if(!vis[ve[x][i]]){
            dfs(ve[x][i],len+1);
        }
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=0;i<n-1;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        ve[u].push_back(v);
        ve[v].push_back(u);
    }
    max_len=0;
    CLR(vis);
    dfs(1,0);    //找到葉子結(jié)點(diǎn)之一,也許是最遠(yuǎn).
    CLR(vis);
    dfs(root,0);    //以一個(gè)葉子結(jié)點(diǎn)開(kāi)始搜素,則搜出來(lái)的長(zhǎng)度一定是最長(zhǎng).
    printf("%d\n",max_len);    //輸出長(zhǎng)度.
}

下面有一道這道題的加強(qiáng)版. (這道題讀懂了的話還是可以敲的,就是我讀題老是喜歡去摳字眼,其實(shí)不太懂時(shí)想想另一種說(shuō)法, 問(wèn)問(wèn)自己這種說(shuō)法是不是也可以符合題目的意思.所以真的要靈活點(diǎn)啊!!!,所以那次比塞真的是我的鍋.)
地址

AC代碼:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#define CLR(x) memset(x,0,sizeof(x))
#define ll long long int
#define PI acos(-1.0)
#define db double
#define mod 1000000007
using namespace std;
const int maxn=1e5+5;
const db eps=1e-6;
const int inf=1e9;
const ll INF=1e15;

struct node
{
    int to,next,w;
}s[maxn*2];  //無(wú)向邊, 所以需要開(kāi)大兩倍.

int head[maxn];
int ans=0;
void add(int u,int to,int w)
{
    s[ans].to=to;
    s[ans].w=w;
    s[ans].next=head[u];
    head[u]=ans++;
}
ll dis1[maxn],dis2[maxn];
int vis[maxn];
void dfs(int x,ll len,ll *dis)   //搜素這棵樹(shù)的直徑.
{
    dis[x]=len;
    vis[x]=1;
    for(int i=head[x];i!=-1;i=s[i].next){
        if(!vis[s[i].to])
            dfs(s[i].to,len+s[i].w,dis);
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n)){
        CLR(dis1);
        CLR(dis2);
        CLR(s);
        memset(head,-1,sizeof(head));
        ans=0;
        for(int i=0;i<n-1;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);   //加邊.
            add(v,u,w);
        }
        CLR(vis);
        dfs(1,0,dis1);   //以任意一個(gè)點(diǎn)去搜索, 搜出來(lái)最遠(yuǎn)的那個(gè)點(diǎn)一定是直徑中的其中一個(gè)點(diǎn).
        int S=0,T=0;
        ll maxx=0;
        for(int i=1;i<=n;i++){
            if(dis1[i]>maxx){
                maxx=dis1[i];
                S=i;   //其中一個(gè)點(diǎn).
            }
        }
        CLR(vis);
        dfs(S,0,dis1);  //在以這個(gè)點(diǎn)去搜索, 最遠(yuǎn)的那個(gè)點(diǎn)就是直徑中的另一個(gè)點(diǎn).
        maxx=0;
        for(int i=1;i<=n;i++){
            if(dis1[i]>maxx){
                maxx=dis1[i];
                T=i;
            }
        }
        //printf("%d %d\n",S,T);
        CLR(vis);
        dfs(T,0,dis2);
        ll res=dis1[T];   //先連接直徑.
        /*for(int i=1;i<=n;i++){
            printf("%d ",dis1[i]);
        }
        printf("\n");*/
        for(int i=1;i<=n;i++){
            if(i == S || i == T) continue;
            res += max(dis1[i],dis2[i]);   //剩余每個(gè)點(diǎn)都選擇里其本身比較遠(yuǎn)的那個(gè)點(diǎn).
        }
        printf("%I64d\n",res);
    }
}

我居然再一次敗在long long 上面, 下次要用ll是我全部用ll了.!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • week11:求樹(shù)的直徑;隨機(jī)選點(diǎn),搜索到距離該點(diǎn)最遠(yuǎn)的一點(diǎn),然后從該點(diǎn)出發(fā)獲得最遠(yuǎn)點(diǎn),兩點(diǎn)間距即為直徑;正常思路...
    vaisy閱讀 457評(píng)論 0 0
  • Given a binary tree, you need to compute the length of th...
    這就是一個(gè)隨意的名字閱讀 911評(píng)論 0 0
  • 我先整理一下吧,不整理的話搞不好過(guò)兩天我自己都忘了樹(shù)的直徑是指一顆樹(shù)上距離最遠(yuǎn)的兩個(gè)點(diǎn)之間的距離。也叫樹(shù)的最長(zhǎng)路樹(shù)...
    陌路晨曦閱讀 1,403評(píng)論 0 0
  • 樹(shù)的直徑(Diameter)是指樹(shù)上的最長(zhǎng)簡(jiǎn)單路。直徑的求法:兩遍BFS (or DFS)任選一點(diǎn)u為起點(diǎn),對(duì)樹(shù)進(jìn)...
    Gitfan閱讀 591評(píng)論 0 0
  • 弗洛伊德算法適用于為圖中每一個(gè)頂點(diǎn)求最短路徑,思路如下 檢查圖中任何一個(gè) 到 任何另一個(gè)點(diǎn)能否通過(guò)第一個(gè)點(diǎn)降低最短...
    RichardW閱讀 1,007評(píng)論 0 1

友情鏈接更多精彩內(nèi)容