求樹的直徑、樹中最長路

http://www.javashuo.com/article/p-dvbugxbr-eb.htmlhtml

概述

對於一顆有邊權的樹,,它的直徑表示樹中最遠的兩個節點之間的距離,,,node

能夠經過兩次深搜(廣搜)來求出直徑ios

分析

從任意起點s開始,,求出到s的最遠的節點node,,而後再從node開始求出到node最遠的節點,,,搜索的過程當中更新節點的值和距離,,c++

(貌似還能夠用樹形dp來求,,,spa

例題

旅行商問題

剛剛作的一道題,,當時感受是兩倍的權值和減去一個最遠的路,,,可是當時不會求最遠的路的距離,,就放棄了,,,後來有人說就是這個思想,,,就看了一下樹的直徑怎麼求,,,固然這題是求出到節點1最遠的路,,不是直徑,,,code

紅書上的板子有點長,,並且建圖方式不怎麼用,,就無論了,,htm

// #include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
//#include <vector>
#include <queue>
#define aaa cout<<233<<endl;
#define endl '\n'
#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

裸題,,求樹的最長路,,也就是直徑,,blog

// #include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
//#include <vector>
#include <queue>
#define aaa cout<<233<<endl;
#define endl '\n'
#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)ci

相關文章
相關標籤/搜索