Tree diameter and its application

Tree diameter:

The diameter of   tree refers to the distance between the two points farthest away from the tree. It has many applications in the tree problem. Usually, a solution with high time complexity can be changed into a linear solution by the nature of the tree diameter.

Nature of tree diameter:

(1) (1) (1) for any point on the tree, the point farthest from it must be one of the two ends of the diameter of the tree;
(2) (2) (2). The two ends of the diameter must be two leaf nodes;
(3) (3) (3) for two trees, if the diameter of the first tree is (u,v)(u,v)(u,v), and the diameter of the second tree is (x,y)(x,y)(x,y), the two ends of the diameter of the new tree must be u,v,x,yu,v,x,yu,v,x,y;
(4) (4) (4). For a tree, if a leaf node is next to a point, then at most one end of the diameter will be changed;
(5) (5) (5). If a tree has multiple diameters, the diameters intersect at one point and the intersection point is the midpoint of the diameters;

Method:
(1) Search (dfs/bfs):

Steps:
                   . The point furthest from the starting point is one of the diameter endpoints. Then the second search is carried out with this point as the starting point, and the point farthest from it is another endpoint.
Complexity: O(n)O(n)O(n)
Easy to record path

(2) Tree dp:

Not yet, post the code first.
Code:

void dp(int st)
{
    vis[st] = true;             //Current node accessed
    for(int i = head[st]; i != -1; i = edge[i].nxt){
        int Eiv = edge[i].v;
        if(vis[Eiv]) continue;  //Don't go back
        dp(Eiv);
        ans_max = max(ans_max, d[st] + d[Eiv] + edge[i].w); //Update tree diameter (updated by the sum of two segments of the current node)
        d[st] = max(d[st], d[Eiv]+edge[i].w);                    //Update the longest path that the current node can take (keep the longer one)
    }
}
Title:

1.Computer HDU - 2196
Find the longest distance from each point, with the edge weight as the distance.
bfs+dfs: finding the end point of tree diameter

#include <bits/stdc++.h>
using namespace std;
const int N=1e4+5;
typedef pair<int,int> P;
vector<P>pic[N];
bool vis[N];
int dis[N],dmax[N];
priority_queue<P,vector<P>,greater<P> >que;
int maxn,ps;
void bfs(int s)
{
    maxn=0;
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));
    while(!que.empty())
        que.pop();
    que.push(make_pair(0,s));
    vis[s]=1;
    while(!que.empty())
    {
        P now=que.top();
        que.pop();
        for(int i=0;i<pic[now.second].size();i++)
        {
            P tmp=pic[now.second][i];
            if(!vis[tmp.second])
            {
                dis[tmp.second]=dis[now.second]+tmp.first;
                if(dis[tmp.second]>maxn)
                {
                    maxn=dis[tmp.second];
                    ps=tmp.second;
                }
                que.push(make_pair(dis[tmp.second],tmp.second));
                vis[tmp.second]=1;
            }
        }
    }

}
void dfs(int v,int p)
{
    for(int i=0;i<pic[v].size();i++)
    {
        P t=pic[v][i];
        if(p!=t.second)
        {
            dis[t.second]=dis[v]+t.first;
            dmax[t.second]=max(dis[t.second],dmax[t.second]);
            dfs(t.second,v);
        }
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int v,w,a,b;
        memset(dmax,0,sizeof(dmax));
        for(int i=1;i<=n;i++)
            pic[i].clear();
        for(int i=2;i<=n;i++)
        {
            scanf("%d%d",&v,&w);
            pic[i].push_back(make_pair(w,v));
            pic[v].push_back(make_pair(w,i));
        }
        bfs(1);
        a=ps;
        bfs(a);
        b=ps;//End point of diameter
        //cout<<"a="<<a<<" b="<<b<<endl;
        memset(dis,0,sizeof(dis));
        dfs(a,-1);
        memset(dis,0,sizeof(dis));
        dfs(b,-1);
        for(int i=1;i<=n;i++)
            printf("%d\n",dmax[i]);

    }
    return 0;
}

2.Cow Marathon POJ - 1985
3.Caterpillar POJ - 3310
                    .
                   . Because the number of points is relatively small, we can use violent methods to find out all the diameters and mark the points on the diameter. Then, traverse all the points to see if they are connected to the unmarked points.

#include <cstdio>//Connected graph, acyclic, diameter
#include <cstring>
#include <vector>
using namespace std;
const int N=110;
vector<int>pic[N];
int pre[N],ff[N];
bool vis[N];
int n,ps,maxn;
int Find(int x)
{
    if(x!=pre[x])
        return pre[x]=Find(pre[x]);
    else
        return x;
}
bool Join(int x,int y)//Combination + judgment
{
    int px=Find(x);
    int py=Find(y);
    if(px==py)
        return false;
    pre[px]=py;
    return true;
}
bool check()
{
    int father=Find(1);
    for(int i=1;i<=n;i++)
    {
        if(father!=Find(i))
            return false;
    }
    return true;
}
void dfs(int v,int p,int d)
{
    ff[v]=p;
    if(d>maxn)
    {
        maxn=d;
        ps=v;
    }
    for(int i=0;i<pic[v].size();i++)
    {
        if(pic[v][i]!=p)
            dfs(pic[v][i],v,d+1);
    }
}
void solve(int s)
{
    while(ff[s]!=-1)
    {
        vis[s]=1;
        s=ff[s];
    }
}
int main()
{
    int e,cnt=0;
    while(scanf("%d",&n),n)
    {
        scanf("%d",&e);
        int u,v;
        bool flag=1;
        for(int i=1;i<=n;i++)
        {
            pic[i].clear();
            pre[i]=i;
        }
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=e;i++)
        {
            scanf("%d%d",&u,&v);
            pic[u].push_back(v);
            pic[v].push_back(u);
            if(!Join(u,v))
                flag=0;
        }
        if(flag)
            flag=check();
        if(flag)
        {
            for(int i=1;i<=n;i++)//Find out all the diameters; n*n
            {
                if(!vis[i])
                {
                    maxn=0;
                    dfs(i,-1,0);
                    dfs(ps,-1,0);//One endpoint to another
                    solve(ps);
                }
            }//Mark all points on diameter
            for(int i=1;i<=n;i++)
            {
                if(vis[i])
                    continue;
                for(int j=0;j<pic[i].size();j++)
                {
                    if(!vis[pic[i][j]])
                    {
                        flag=0;
                        break;
                    }
                }
            }
        }
        if(!flag)
            printf("Graph %d is not a caterpillar.\n",++cnt);
        else
            printf("Graph %d is a caterpillar.\n",++cnt);

    }
    return 0;
}

4.codeforce 1294F-Three Paths on a Tree
Title Solution

Published 101 original articles, won praise 9, visited 1503
Private letter follow

Posted on Mon, 03 Feb 2020 07:00:17 -0500 by gozbay.com