zoukankan      html  css  js  c++  java
  • 树的直径问题模板及其原理

    /*树的直径是指树的最长简单路。求法: 两遍BFS :先任选一个起点BFS找到最长路的终点,再从终点进行BFS,则第二次BFS找到的最长路即为树的直径;
    原理: 设起点为u,第一次BFS找到的终点v一定是树的直径的一个端点
    证明: 1) 如果u 是直径上的点,则v显然是直径的终点(因为如果v不是的话,则必定存在另一个点w使得u到w的距离更长,则于BFS找到了v矛盾)
    2) 如果u不是直径上的点,则u到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了
    所以v一定是直径的一个端点,所以从v进行BFS得到的一定是直径长度
    */

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define MOD 100000000
    #define inf 2147483640
    
    using namespace std;
    
    const int maxn=30010;
    struct edge {int to,next,w;}e[maxn<<1];
    int n,m,rt,ans,cnt,head[maxn];
    
    void link(int u,int v,int w) {
        e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;
        e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;e[cnt].w=w;
    }
    void dfs(int x,int fa,int d) {
        if (ans<d) ans=d,rt=x;
        for (int i=head[x];i;i=e[i].next)
            if (e[i].to!=fa) dfs(e[i].to,x,d+e[i].w);
    }
    void init()
    {
        memset(head,0,sizeof(head));
        cnt=0;
    }
    int main() {
    
        while(scanf("%d",&n)!=EOF)
        {
            init( );
        for (int u,v,w,i=1;i<=n;i++) {
            scanf("%d%d%d",&u,&v,&w);
            link(u,v,w);
        }
        rt=ans=0;dfs(1,0,0);
        dfs(rt,0,0);
        printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    快速读取数字
    std:ios:sync_with_stdio (false)以及局限性
    差分,差分数组
    归并排序
    2020-07-06日报博客
    OAuth2-授权码模式 登录流程
    OAuth2 简介
    SpringSecurity连接数据库
    SpringSecurity中的授权
    SpringSecurity 入门
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9175984.html
Copyright © 2011-2022 走看看