zoukankan      html  css  js  c++  java
  • 求树的直径、树中最长路

    https://www.cnblogs.com/31415926535x/p/10543619.html

    概述

    对于一颗有边权的树,,它的直径表示树中最远的两个节点之间的距离,,,

    可以通过两次深搜(广搜)来求出直径

    分析

    从任意起点s开始,,求出到s的最远的节点node,,然后再从node开始求出到node最远的节点,,,搜索的过程中更新节点的值和距离,,

    (貌似还可以用树形dp来求,,,

    例题

    旅行商问题

    刚刚做的一道题,,当时感觉是两倍的权值和减去一个最远的路,,,但是当时不会求最远的路的距离,,就放弃了,,,后来有人说就是这个思想,,,就看了一下树的直径怎么求,,,当然这题是求出到节点1最远的路,,不是直径,,,

    红书上的板子有点长,,而且建图方式不怎么用,,就不管了,,

    // #include <bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <string.h>
    //#include <vector>
    #include <queue>
    #define aaa cout<<233<<endl;
    #define endl '
    '
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int inf = 0x3f3f3f3f;//1061109567
    const ll linf = 0x3f3f3f3f3f3f3f;
    const double eps = 1e-6;
    const double pi = 3.14159265358979;
    const int maxn = 1e5 + 5;
    const int maxm = 2e5 + 5;
    const int mod = 1e9 + 7;
    struct edge
    {
        int to, next, w;
    }edge[maxn];
    int tot, head[maxn];
    void init()
    {
        tot = 0;
        memset(head, -1, sizeof head);
    }
    void addedge(int u, int v, int w)
    {
        edge[tot].to = v;
        edge[tot].w = w;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    int ans, node, sum;
    int dis[maxn];
    bool vis[maxn];
    void dfs(int u)
    {
        for(int i = head[u]; ~i; i = edge[i].next)
        {
            int v = edge[i].to;
            if(!vis[v])
            {
                vis[v] = true;
                dis[v] = dis[u] + edge[i].w;
                if(dis[v] > ans)
                {
                    ans = dis[v];
                    node = v;
                }
                dfs(v);
            }
        }
    }
    void bfs(int s, int n)
    {
        queue<int> q;
        while(!q.empty())q.pop();
        q.push(s);
        vis[s] = true;
        while(!q.empty())
        {
            int u = q.front(); q.pop();
            for(int i = head[u]; ~i; i = edge[i].next)
            {
                int v = edge[i].to;
                if(!vis[v])
                {
                    vis[v] = true;
                    dis[v] = dis[u] + edge[i].w;
                    q.push(v);
                    if(dis[v] > ans)
                    {
                        ans = dis[v];
                        node = v;
                    }
                }
            }    
        }
        
    }
    void solve(int n)
    {
        // memset(dis, 0, sizeof dis);
        // memset(vis, false, sizeof vis);
        // ans = 0;
        // node = 0;
        // vis[1] = true;
        // dfs(1);
        memset(dis, 0, sizeof dis);
        memset(vis, false, sizeof vis);
        ans = 0;
        node = 0;
        vis[1] = true;
        bfs(1, n);
        ans = sum * 2 - ans;
        cout << ans << endl;
    }
    int main()
    {
    //    freopen("233.in" , "r" , stdin);
    //    freopen("233.out" , "w" , stdout);
        ios_base::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
        int n; cin >> n;
        int u, v, w;
        init();
        sum = 0;
        for(int i = 1; i <= n - 1; ++i)
        {
            cin >> u >> v >> w;
            addedge(u, v, w);
            addedge(v, u, w);
            sum += w;
        }
        solve(n);
        return 0;
    }
    
    

    Roads in the North

    裸题,,求树的最长路,,也就是直径,,

    // #include <bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <string.h>
    //#include <vector>
    #include <queue>
    #define aaa cout<<233<<endl;
    #define endl '
    '
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int inf = 0x3f3f3f3f;//1061109567
    const ll linf = 0x3f3f3f3f3f3f3f;
    const double eps = 1e-6;
    const double pi = 3.14159265358979;
    const int maxn = 1e5 + 5;
    const int maxm = 2e5 + 5;
    const int mod = 1e9 + 7;
    struct edge
    {
        int to, next, w;
    }edge[maxn];
    int tot, head[maxn];
    void init()
    {
        tot = 0;
        memset(head, -1, sizeof head);
    }
    void addedge(int u, int v, int w)
    {
        edge[tot].to = v;
        edge[tot].w = w;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    int dis[maxn];
    bool vis[maxn];
    int ans, node;
    void dfs(int u)
    {
        for(int i = head[u]; ~i; i = edge[i].next)
        {
            int v = edge[i].to;
            if(!vis[v])
            {
                dis[v] = dis[u] + edge[i].w;
                vis[v] =true;
                if(dis[v] > ans)
                {
                    ans = dis[v];
                    node = v;
                }
                dfs(v);
            }
        }
    }
    void solve()
    {
        memset(vis, false, sizeof vis);
        memset(dis, 0, sizeof dis);
        ans = 0;
        node = 0;
        vis[1] = true;
        dfs(1);
    
        memset(vis, false, sizeof vis);
        memset(dis, 0, sizeof dis);
        vis[node] = true;
        ans = 0;
        dfs(node);
        printf("%d", ans);
    }
    int main()
    {
    //    freopen("233.in" , "r" , stdin);
    //    freopen("233.out" , "w" , stdout);
        // ios_base::sync_with_stdio(0);
        // cin.tie(0);cout.tie(0);
        init();
        int u, v, w;
        while(~scanf("%d%d%d", &u, &v, &w))
        {
            addedge(u, v, w);
            addedge(v, u, w);
        }
        solve();
        return 0;
    }
    
    

    (end)

  • 相关阅读:
    centos7下mysql双主+keepalived
    Nginx 性能优化有这篇就够了!
    mysql对自增主键ID进行重新排序
    nginx 配置文件 2019-12-20
    zabbix服务端接收的数据类型,便于编写脚本向服务端提交数据
    zabbix自动注册,实现自动添加机器,减少人工干预
    zabbix企业微信告警配置教程
    websocket 连接测试端口服务是否正常代码
    mongodb Sort排序能够支持的最大内存限制为32M Plan executor error during find: FAILURE
    rabbitmq 的安装配置使用
  • 原文地址:https://www.cnblogs.com/31415926535x/p/10543619.html
Copyright © 2011-2022 走看看