求树的直径、树中最长路
https://www.cnblogs.com/31415926535x/p/10543619.html
概述
对于一颗有边权的树,,它的直径表示树中最远的两个节点之间的距离,,,
可以通过两次深搜(广搜)来求出直径
分析
从任意起点s开始,,求出到s的最远的节点node,,然后再从node开始求出到node最远的节点,,,搜索的过程中更新节点的值和距离,,
例题
旅行商问题
刚刚做的一道题,,当时感觉是两倍的权值和减去一个最远的路,,,但是当时不会求最远的路的距离,,就放弃了,,,后来有人说就是这个思想,,,就看了一下树的直径怎么求,,,当然这题是求出到节点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 '\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
裸题,,求树的最长路,,也就是直径,,
// #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)
剑之所指,心之所向,身之所往!!!