2015百度笔试编程-树的直径
题目描述
n个城市,任意城市城市之间可达且只有唯一的路径。现在有一个G商队在这n个城市之间运输货物,运输货物与运输距离有关,在走第x千米到第x+1千米的时候,花费10+x。现在G商队想知道从某一个城市出发到达另一个城市最多花费是多少。
输入:第一行整数n,表示城市数;接下来n-1行,表示n-1条路,每行Pi,Qi,Di,表示Pi到Qi有一条长为Di的路。城市编号从1开始。
输出:一行,整数,表示最大花费。
算法描述
很显然,n个城市构成一个树,要求的是树上最长的路径,也就是树的直径。求树的直径可以通过两次dfs求得,具体:
- 从任意一点u开始dfs,找出距离u最远的点v1。v1一定是直径上的一个端点;
- 从v1出发dfs,找出距离v1最远的点v2,则v1-v2就是树的直径。
代码
用一个二维vector构建图的邻接表很方便。
#include <stdio.h>
#include <vector>
#include <iostream>
using namespace std;
struct G {
int v, w;
G() : v(0), w(0) {}
G(int _v, int _w) : v(_v), w(_w) {}
};
vector< vector<G> > g;
void dfs(int p, int u, int cost, int &maxc, int &endpoint)
{
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i].v;
int w = g[u][i].w;
if (v == p) continue;
cost += w;
if (cost > maxc) {
maxc = cost;
endpoint = v;
}
dfs(u, v, cost, maxc, endpoint);
cost -= w;
}
return ;
}
int main ()
{
int n, u, v, w;
cin >> n;
g.resize(n+1);
for (int i = 0; i < n-1; i++) {
cin >> u >> v >> w;
g[u].push_back(G(v, w));
g[v].push_back(G(u, w));
}
int maxc = 0, endpoint1 = 0, endpoint2 = 0;
dfs(-1, 1, 0, maxc, endpoint1);
maxc = 0;
dfs(-1, endpoint1, 0, maxc, endpoint2);
cout << maxc*10 + maxc*(maxc+1)/2 << endl;
return 0;
}
goudan-er SHARE · ALGORITHM
Algorithm