2019牛客国庆集训派对day4 H Highway(树的直径 - bfs)

链接:https://ac.nowcoder.com/acm/contest/1109/H
来源:2019牛客国庆集训派对day4
证明:https://blog.csdn.net/qq_42217376/article/details/102148990

  • 题目描述
    在这里插入图片描述
  • 输入描述:
    The input contains zero or more test cases and is terminated by end-of-file. For each test case:
    The first line contains an integer n.
    The i-th of the following (n - 1) lines contains three integers aia_iai​, bib_ibi​ and cic_ici​.
    1 n 1 0 5 1≤ n ≤10^{5}
    1 a i , b i n 1≤a_{i},b_{i}≤n
    1 c i 1 0 8 1≤c_{i}≤10^{8}
    The number of test cases does not exceed 10.
  • 输出描述:
    For each test case, output an integer which denotes the result.
  • 输入
    5
    1 2 2
    1 3 1
    2 4 2
    3 5 1
    5
    1 2 2
    1 4 1
    3 4 1
    4 5 2
  • 输出
    19
    15

  题意: n n 个城镇被 n 1 n-1 条路连接,现在 B o b o Bobo 想要花钱建 n 1 n-1 条铁路使得每个城镇都联通,并且任意两个城镇之间只有一条路径。求出 B o b o Bobo 的最大花费。
  思路:我们先找到给出的树的树的直径,那么树的直径上的两个端点一定是最远的,对于其他的点我们取到这两个端点最远的一条路径即可。最后计算所有端点到这个端点的最大值相加,注意这里多加了一个树的直径,减去一个直径即为最终答案。

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int Max_n=1e5+10;
int head[Max_n],cnt,mmaxdot,n;
ll dis[Max_n],ans,disdot1[Max_n],disdot2[Max_n];
bool vis[Max_n];

struct Edge{
    int u,v,w,next;
}edge[Max_n<<1];

void addedge(int u,int v,int w){
    edge[cnt].u=u; edge[cnt].v=v;
    edge[cnt].w=w; edge[cnt].next=head[u];
    head[u]=cnt++;
}

void bfs(int s){
    memset(vis,false,sizeof(vis));
    memset(dis,0,sizeof(dis));
    queue<int>q; ans=0; mmaxdot=0;
    q.push(s); vis[s]=true;
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].v;
            if(!vis[v]){
                if(dis[v]<dis[u]+(ll)edge[i].w){
                    dis[v]=dis[u]+(ll)edge[i].w;
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
    for(int i=1;i<=n;i++){
        if(ans<dis[i]){
            ans=dis[i]; mmaxdot=i;
        }
    }
}

int main(){
    while(~scanf("%d",&n)){ cnt=0;
        for(int i=1;i<=n;i++){ head[i]=-1,disdot1[i]=0,disdot2[i]=0; }
        for(int i=1;i<=n-1;i++){
            int u,v,w; scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w); addedge(v,u,w);
        }
        bfs(1); bfs(mmaxdot);
        //for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
        //cout<<endl<<mmaxdot<<endl;
        for(int i=1;i<=n;i++) disdot1[i]=dis[i];
        bfs(mmaxdot); ll Max=ans;
        //for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
        //cout<<endl<<mmaxdot<<endl;
        for(int i=1;i<=n;i++) disdot2[i]=dis[i];
        ll res=0;
        for(int i=1;i<=n;i++) res+=max(disdot1[i],disdot2[i]);
        printf("%lld\n",res-Max);
    }
    return 0;
}


/**
* Copyright(c)
* All rights reserved.
* Author : Max_n
* Date : 2019-10-05-15.56.59
* Description : 树的直径 - bfs
*/
发布了166 篇原创文章 · 获赞 68 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_42217376/article/details/102155319