樹的直徑總結【模板】


樹的直徑:一棵樹中從一個節點到另一個節點的一條最長的路徑,這條路徑可以只是這個樹上的部分節點,也可以是所有節點(主要看這棵樹的連接方式)在這個路徑上任意節點的分岔不予考慮            

求法:先任意選擇一個節點a當做起點來找到距離這個點最遠的端點b(這兩點之間的路徑上所有邊的權值和最大),然后再以b節點為起點找到距離b點最遠的節點c此時b點到c點的距離就是這棵樹上路徑最長的距離。

實現:因為求樹的直徑題目數據量往往比較大,所以用鄰接表來儲存數據;至於對兩個端點的查找通過bfs實現,先將第一次選擇的起點a隊然后開始搜索與a連接的所有邊,並將權值存入dis[]數組 dis[x]=dis[top]+edge[i].w(dis[x]指的是當前搜索到的點與之前與它相 連的搜索過邊的總權值,dis[top]是指當前搜索到的點的之前與它相連的搜索過邊的總權值,edge[i].w是點top到當前搜索到的點 的連線的權值)完成於對當前點的搜索后,將其入隊,然后對下一個點進行此操作,每次搜索時,同時將最大的權值存入sum中如此重復直至隊列為空,這樣這個搜素結束后,sum的值就是a點到距離其最遠的點b的總權值之和;此時再以b為起點進行第二次搜索(第 二次搜 索步驟與第一次相同)

                            鄰接表不會?點我

 

#include<stdio.h>
#include<string.h>
#include<queue>
#define MAX 100000
using namespace std;
int head[MAX];
int vis[MAX];//標記當前節點是否已經用過 
int dis[MAX];//記錄最長距離 
int n,m,ans;
int sum;//記錄最長路徑的長度 
int aga;
struct node
{
    int u,v,w;
    int next;
}edge[MAX];
void add(int u,int v,int w)//向鄰接表中加邊 
{
    edge[ans].u=u;
    edge[ans].v=v;
    edge[ans].w=w;
    edge[ans].next=head[u];
    head[u]=ans++;
}
void getmap()
{
    int i,j;
    int a,b,c;
    ans=0;
    memset(head,-1,sizeof(head));
    while(m--)
    {
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
        add(b,a,c);
    }
}
void bfs(int beg)
{
    queue<int>q;
    memset(dis,0,sizeof(dis));
    memset(vis,0,sizeof(vis));
    int i,j;
    while(!q.empty())
        q.pop();
    aga=beg;
    sum=0;
    vis[beg]=1;
    q.push(beg);
    int top;
    while(!q.empty())
    {
        top=q.front();
        q.pop();
        for(i=head[top];i!=-1;i=edge[i].next)
        {
            if(!vis[edge[i].v])
            {
                dis[edge[i].v]=dis[top]+edge[i].w;
                vis[edge[i].v]=1;
                q.push(edge[i].v);
                if(sum<dis[edge[i].v])
				{
					sum=dis[edge[i].v];
					aga=edge[i].v;
				} 
            }
        }
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        getmap();
        bfs(1);//搜索最長路徑的一個端點 
        bfs(aga);//搜索另一個端點 
        printf("%d\n",sum);
    }
    return 0;
}

  

 


免責聲明!

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



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