zoukankan      html  css  js  c++  java
  • BDFZOI 树的直径

    提交次数:2

    涉及知识:基础图论/BFS

    描述

    一棵树T的“直径”定义为结点两两间距离的最大值。给定带权树T,求T的直径长度。

    输入

    第一行包含2个整数N、M,表示图中共有N个结点和M条无向边。(N <= 5000,M<n)
    接下来M行,每行包含3个整数{u,v,w},表示有一条无向边连接结点u、v
    *输入保证是无环图输出一个整数,代表直径长度

    样例输入

    4 3
    1 2 1
    2 3 2
    2 4 3

    样例输出

    5

    代码:

     1 #include<iostream>
     2 #include<vector>
     3 #include<queue>
     4 #include<cstring>
     5 using namespace std;
     6 struct node{
     7     int v, w;
     8     node(int vv, int ww):v(vv),w(ww){}
     9 };
    10 struct bnode{
    11     int x, step;
    12     bnode(int xx, int ss):x(xx),step(ss){}
    13 };
    14 vector<vector<node> >tree(5005);
    15 queue<bnode>q;
    16 bool visited[5005];
    17 int dis[5005];
    18 int firstu, diameter; //第一次BFS扩展到的点 
    19 int n, m;
    20 
    21 void bfs(int u){
    22     memset(visited,0,sizeof(visited));
    23     visited[u] = true;
    24     while(!q.empty()){q.pop();}
    25     q.push(bnode(u,0));
    26     while(!q.empty()){
    27         bnode bb = q.front();
    28         for(int i = 0; i < tree[bb.x].size(); i++){
    29             int next = tree[bb.x][i].v;
    30             if(!visited[next]){
    31                 q.push(bnode(next,bb.step+tree[bb.x][i].w));
    32                 visited[next] = true;
    33             }
    34         }
    35         dis[bb.x] = bb.step;
    36         q.pop();
    37     }
    38     diameter = -1;
    39     for(int i = 1; i <= n; i++){
    40         if(dis[i]>=diameter){
    41             diameter = dis[i];
    42             firstu = i;
    43         }
    44     }
    45 }
    46 int main(){
    47     cin>>n>>m;
    48     for(int i = 1; i <= m; i++){
    49         int a, b, c;
    50         cin>>a>>b>>c;
    51         tree[a].push_back(node(b,c));
    52         tree[b].push_back(node(a,c));
    53     }
    54     bfs(1);
    55     //cout<<firstu<<endl;
    56     bfs(firstu);
    57     cout<<diameter<<endl;
    58     return 0;
    59 }

    备注:

    树的直径,顾名思义,就是树上一条最长路,一个经典算法就是两次BFS。证明略,因为我不会。

    先从树上任意一个点出发BFS到头,这时这个端点一定是直径的一端,证明略……这是第一遍BFS。

    然后再从这个点BFS到头,找到的最长路就是直径。 这是第二遍BFS。

  • 相关阅读:
    TextView 显示内容时出现 ArrayIndexOutOfBoundsException 的解决方法(Android 4.1)
    Android Activity 启动模式和任务栈
    Android 坐标系和 MotionEvent 分析、滑动
    Android 控件架构及View、ViewGroup的测量
    Android Studio 3.0 及以上版本使用技巧总结
    移动端开发网络优化建议
    Netty系列之Netty高性能之道
    并发框架Disruptor译文
    Python轻量Web框架Flask使用
    修改MySQL的时区,涉及参数time_zone
  • 原文地址:https://www.cnblogs.com/fangziyuan/p/6980328.html
Copyright © 2011-2022 走看看