小A与欧拉路(树的直径)

链接:https://ac.nowcoder.com/acm/contest/369/C
来源:牛客网
 

小A与欧拉路

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

小A给你了一棵树,对于这棵树上的每一条边,你都可以将它复制任意(可以为0)次(即在这条边连接的两个点之间再加一条边权相同的边),求所有可能新形成的图中欧拉路的最短长度

欧拉路:从图中任意一个点开始到图中任意一个点结束的路径,并且图中每条边只通过恰好一次

输入描述:

第一行一个数 n ,表示节点个数

接下来 n-1 行,每行三个整数 u,v,w,表示有一条 u 到 v 边权为 w 的无向边

保证数据是一棵树

输出描述:

一行一个整数,表示答案

示例1

输入

复制

4
1 2 1
1 3 1
1 4 2

输出

复制

5

说明

一种可能的方案为复制 <1,2,1> 这条边一次,欧拉路为4->1->2->1->3

备注:

 

1≤n≤2×1051≤n≤2×105
1≤ui,vi≤n1≤ui,vi≤n
1≤wi≤1041≤wi≤104

扫描二维码关注公众号,回复: 6060524 查看本文章

题解:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
ll d[maxn],n;
bool vis[maxn];
struct node
{
    int v;
    ll w;
    node(int a,int b){
        v=a;
        w=b;
    }
};
vector<node >G[maxn];
void dfs(int u)
{
    vis[u]=1;
    int siz=G[u].size();
    for(int i=0;i<siz;i++)
    {
        int v=G[u][i].v;
        if(vis[v]) continue;
        d[v]=d[u]+G[u][i].w;
        dfs(v);
    }
}
int main()
{
    cin>>n;
    int u,v;
    ll w;
    ll res=0;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d%lld",&u,&v,&w);
        G[u].push_back(node(v,w));
        G[v].push_back(node(u,w));
        res+=w;
    }
    dfs(1);
    int start=1;
    ll mx=-1;
    for(int i=1;i<=n;i++)
    {
        if(d[i]>mx)
        {
            mx=d[i];
            start=i;
        }
    }
    memset(d,0,sizeof(d));
    memset(vis,0,sizeof(vis));
    dfs(start);
    mx=-1;
    for(int i=1;i<=n;i++)
    {
        if(d[i]>mx)
        {
            mx=d[i];
            start=i;
        }
    }
    cout<<res*2-mx<<endl;
}

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/89336485