求树的直径、树中最长路

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

概述

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

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

分析

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

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

例题

旅行商问题

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

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

// #include 
#include 
#include 
#include 
#include 
//#include 
#include 
#define aaa cout<<233< ans)
            {
                ans = dis[v];
                node = v;
            }
            dfs(v);
        }
    }
}
void bfs(int s, int n)
{
    queue 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 
#include 
#include 
#include 
#include 
//#include 
#include 
#define aaa cout<<233< 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)

你可能感兴趣的:(求树的直径、树中最长路)