• 牛客练习赛27 C-水图


    小w不会离散数学,所以她van的图论游戏是送分的

    小w有一张n个点n-1条边的无向联通图,每个点编号为1~n,每条边都有一个长度
    小w现在在点x上
    她想知道从点x出发经过每个点至少一次,最少需要走多少路

    输入描述:

    第一行两个整数 n,x,代表点数,和小w所处的位置
    第二到第n行,每行三个整数 u,v,w,表示u和v之间有一条长为w的道路

    输出描述:

    一个数表示答案

    示例1

    输入

    复制

    3 1
    1 2 1
    2 3 1

    输出

    复制

    2

    基本思想:设想这是一棵树,从根出发想要走遍所有的节点,一定会从分叉处返回,最后一条分叉不必返回,所以我们可以找出最长的一条分叉路径,然后用2倍的路径总长-最长的分叉路径即得可以走遍所有节点的最短路径。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    struct node
    {
        int nex,d;
        node(int a,int b)
        {
            nex = a,d = b;
        }
    };
    
    vector<node>v[50010];
    bool vis[50010];
    ll ans;
    void dfs(int s,ll dis)
    {
        vis[s] = 1;//标记已访问的节点
        int size = v[s].size();
        if(size == 1 && vis[v[s][0].nex])//度数为1且与它相连的节点已访问
        {
            ans = max(ans,dis);
            return ;
        }
        for(int i = 0;i < size;i ++)
        if(!vis[v[s][i].nex])//与它相连的节点未访问
        dfs(v[s][i].nex,dis + v[s][i].d);
    }
    
    int main()
    {
        int n,x,u,k,w;
        ll sum = 0;
        while(cin >> n >> x)
        {
            for(int i = 1;i < n;i ++)
            {
                cin >> u >> k >> w;
                v[u].push_back(node(k,w));
                v[k].push_back(node(u,w));
                sum += w;
            }
            dfs(x,0);//x为起点,0为初始距离
            cout << 2 * sum - ans << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    BOM和DOM
    前端CSS
    前端HTML
    索引 创建用户和授权 锁 事务
    多表查询 Naricat pymysql
    外键关联的修改 级联 修改表行记录的操作
    表的基础数据类型 MySQL的mod设置 表的约束
    数据库初识及操作命令
    LINUX 下LAMP之源码环境部署
    Nginx负载均衡配置实例详解【原】
  • 原文地址:https://www.cnblogs.com/lu1nacy/p/10016630.html
Copyright © 2020-2023  润新知