zoukankan      html  css  js  c++  java
  • LightOJ 1094

    http://lightoj.com/volume_showproblem.php?problem=1094

    树的直径是指树的最长简单路。

    求法: 两遍BFS :先任选一个起点BFS找到最长路的终点,再从终点进行BFS,则第二次BFS找到的最长路即为树的直径;

    原理: 设起点为u,第一次BFS找到的终点v一定是树的直径的一个端点


    证明:

    1) 如果u 是直径上的点,则v显然是直径的终点(因为如果v不是的话,则必定存在另一个点w使得u到w的距离更长,则于BFS找到了v矛盾)
    2) 如果u不是直径上的点,则u到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了
    所以v一定是直径的一个端点,所以从v进行BFS得到的一定是直径长度

    详细证明请参考:

    http://www.cnblogs.com/wuyiqi/archive/2012/04/08/2437424.html

    #include <cstdio>
    #include <cstring>
    #include <ostream>
    #include <algorithm>
    
    using namespace std;
    
    #define N 30010
    
    struct Edge
    {
        int u, v, next, l;
    }edge[N * 4];
    
    int head[N], dist[N], Max, cnt, Index;
    
    void Init()
    {
        memset(head, -1, sizeof(head));
        cnt = 0;
    }
    
    void AddEdge(int u, int v, int l)
    {
        edge[cnt].u = u;
        edge[cnt].v = v;
        edge[cnt].l = l;
        edge[cnt].next = head[u];
        head[u] = cnt++;
    }
    
    void DFS(int u, int l)
    {
        int v, i;
        dist[u] = l;
        if(dist[u] > Max)
        {
            Max = dist[u];
            Index = u;
        }
        for(i = head[u] ; i != -1 ; i = edge[i].next)
        {
            v = edge[i].v;
            if(dist[v] == -1)
                DFS(v, edge[i].l + dist[u]);
        }
    }
    
    int main()
    {
        int t, n, u, v, l, i, x = 0;
        scanf("%d", &t);
        while(t--)
        {
            x++;
            Init();
            scanf("%d", &n);
            for(i = 1 ; i < n ; i++)
            {
                scanf("%d%d%d", &u, &v, &l);
                AddEdge(u, v, l);
                AddEdge(v, u, l);
            }
            Max = 0;
            memset(dist, -1, sizeof(dist));
            DFS(0, 0);//以树中任意一个结点为源点(这里暂且选0当源点),进行一次广度优先遍历,找出离源点距离最远的点Index
            memset(dist, -1, sizeof(dist));
            DFS(Index, 0);//以Index为源点,进行一次广度优先遍历,找出离Index最远的点,并记录其长度,该长度即为树的直径
            printf("Case %d: %d
    ", x, Max);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Day 09 文件处理
    Day 08 字符编码
    day 07 猜年龄
    Day 07 元组/字典/集合/python深浅拷贝
    Day 06 猜年龄/三级菜单
    并发编程-Atomic的compareAndSet
    并发编程-多线程共享变量不安全
    Spring boot Junit单元测试回滚
    Java 不区分大小写比较字符串
    IDEA 设置html 和js热发布
  • 原文地址:https://www.cnblogs.com/qq2424260747/p/4740347.html
Copyright © 2011-2022 走看看