• 牛客练习赛40 B.小A与欧拉路


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

    题目描述

    小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

    备注:

    1n2×1051≤n≤2×105
    1ui,vin1≤ui,vi≤n
    1wi1041≤wi≤104


    题解:容易得出,本题转化为求一条主链,所有支链上的边都复制一次,从主链上的端点沿主链前进,当某点上连有支链时,走到支链终点再走回该点。
       所以问题转化为要使得主链所占权值尽可能大,即求树的直径。
       最终结果ans = sgma{w×2}-直径上的权值。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n;
     4 const int N = 200005;
     5 int head[N];
     6 struct Edge{
     7     int to,w,next;
     8 }edge[N*2];
     9 int tol;
    10 typedef long long ll;
    11 int ret;
    12 bool vis[N];
    13 int dis[N];
    14 void init(){
    15     tol = 0;
    16     memset(head,-1,sizeof(head));
    17 }
    18 
    19 void addedge(int u,int v,int w){
    20     edge[tol] = Edge{v,w,head[u]};
    21     head[u] = tol++;
    22 }
    23 
    24 int bfs(int s){
    25     memset(dis,0,sizeof(dis));
    26     memset(vis,0,sizeof(vis));
    27     queue<int> q;
    28     q.push(s);
    29     vis[s] = 1;
    30     int len = 0;
    31     while(!q.empty()){
    32         int u = q.front();
    33         q.pop();
    34         for (int i = head[u];i != -1;i = edge[i].next){
    35             int v = edge[i].to;
    36             if (vis[v]) continue;
    37             dis[v] = dis[u] + edge[i].w;
    38             if (len < dis[v]){
    39                 len = dis[v];
    40                 ret = v;
    41             }
    42             vis[v] = 1;
    43             q.push(v);
    44         }
    45     }
    46     return len;
    47 }
    48 
    49 int main(){
    50     init();
    51     scanf("%d",&n);
    52     ll ans = 0;
    53     for (int i = 0;i < n-1;++i){
    54         int u,v,w;
    55         scanf("%d%d%d",&u,&v,&w);
    56         addedge(u,v,w);
    57         addedge(v,u,w);
    58         ans += w << 1;
    59     }
    60     bfs(1);
    61     int v = bfs(ret);
    62     printf("%lld
    ",ans - v);
    63     return 0;
    64 }
  • 相关阅读:
    新书《JFinal极速开发实战》正式发布
    Maven转化为Dynamic Web Module
    SpringMVC——数据校验
    SpringMVC——请求映射
    Spring——Bean的命名及实例化
    js实现省市区三级联动
    MySQL数据库忘记密码
    Spring——控制反转
    SpringMVC(五)@RequestHeader和@CookieValue
    SpringMVC(四)@RequestParam
  • 原文地址:https://www.cnblogs.com/mizersy/p/10395714.html
Copyright © 2020-2023  润新知