zoukankan      html  css  js  c++  java
  • 树的直径-蓝桥杯大臣的旅费

    蓝桥杯大臣的旅费

    树的直径理论

    首先从u dfs找到最远点v ,然后从v开始,dfs找到的最远点一定是树的直径
    证明:
    如果u->v 和树的直径没有公共点,则可以从树的直径终点到u引一条边,树直径变长了,矛盾
    假设交点为k,那么k->v (或者就是v本身) 一定是树直径的一部分,(最优子结构)
    这样就证明了v一定在树的直径的端点处,(为什么是端点,因为u->v是最远的,一定是叶子节点)

    代码:

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <vector>
     5 using namespace std;
     6  
     7 const int maxn = 1e6 + 5;
     8 int n, max_dis = -1, vis[maxn], start;
     9 vector<int> g[maxn];
    10 vector<int> e[maxn];
    11  
    12 int cal(int x)
    13 {
    14     int res = 0;
    15     for(int i=1;i<=x;++i)res+=(i+10);
    16     return res;
    17 }
    18 
    19 void dfs(int u,int sum)
    20 {
    21     vis[u] = 1;
    22     if(sum>max_dis)
    23     {
    24         max_dis = sum;
    25         start = u;
    26     }
    27     for(int i=0;i<g[u].size();++i)
    28     {
    29         if(!vis[g[u][i]]) dfs(g[u][i],sum+e[u][i]);
    30     }
    31 }
    32  
    33 int main()
    34 {
    35     freopen("input.txt","r",stdin);
    36     cin>>n;
    37     int u,v,k;
    38     for (int i=0;i<n-1;++i)
    39     {
    40         cin>>u>>v>>k;
    41         g[u-1].push_back(v-1);
    42         g[v-1].push_back(u-1);
    43         e[u-1].push_back(k);
    44         e[v-1].push_back(k);
    45     }
    46     dfs(0,0);
    47     //任意取一个点寻找最远的结点start
    48     max_dis=-1;
    49     memset(vis,0,sizeof(vis));
    50     dfs(start,0);//从start开始求解树的直径
    51     //重置深搜时使用的变量
    52     cout<<cal(max_dis)<<endl;
    53     return 0;
    54 }

    OK

  • 相关阅读:
    Nhibernate 简单实例(一)
    Sql 行转列
    EasyUI TreeGrid 的使用
    MSMQ消息队列的简单使用
    实体类与DataTable互换
    给Config的appSettings节点赋值
    Angular js (2)
    Angular JS 入门
    用Aspose.Cells 导出为自定义格式的excel
    【多线程学习笔记整理】002_线程的停止、暂停、与yield
  • 原文地址:https://www.cnblogs.com/savennist/p/12570262.html
Copyright © 2011-2022 走看看