1207. 大臣的旅费
很久以前,T王国空前繁荣。
为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。
为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。
同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。
J是T国重要大臣,他巡查于各大城市之间,体察民情。
所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。
他有一个钱袋,用于存放往来城市间的路费。
聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。
J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?
输入格式
输入的第一行包含一个整数 n
,表示包括首都在内的T王国的城市数。
城市从 1开始依次编号,1号城市为首都。
接下来 n−1行,描述T国的高速路(T国的高速路一定是 n−1条)。
每行三个整数 Pi,Qi,Di,表示城市 Pi和城市 Qi之间有一条双向高速路,长度为 Di千米。
输出格式
输出一个整数,表示大臣J最多花费的路费是多少。
数据范围
1≤n≤105,
1≤Pi,Qi≤n,
1≤Di≤1000
输入样例:
5
1 2 2
1 3 1
2 4 5
2 5 4
输出样例:
135
树的直径
首先分析一下题目,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。即这是一个树状的,不会形成一个环,求最大路费,即求树某两个点最大距离,也叫树的直径。
求树的直径,即先随便找一个点A,找到和点A距离最远的点B,再找到距离B点最远的点C,B和C的距离即树的直径。
简要证明如下:
可知:
x1>=x2
x1+x2>=x1+x3
故 x2>=x3
所以树的直径就是x1+x2
题解
思路:用结构体保存某个点能到达的点以及距离,记得开longlong,数组dist保存到达某个点的距离是多少,另外还要记录每个点相邻的点有哪些,dfs的时候记录父节点,避免重复dfs,两次dfs即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dist[111111];
vector<int> y[111111];
struct node
{
int id,w;
};
vector<node> v[111111];
void dfs(int x,int fa,ll path)
{
dist[x]=path;
for(auto p:v[x])
{
if(p.id!=fa) dfs(p.id,x,path+p.w);
}
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n-1;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
v[a].push_back({b,c});
v[b].push_back({a,c});
}
dfs(1,-1,0);
ll num,big=0;
for(int i=1;i<=n;i++)
{
big=max(big,dist[i]);
if(big==dist[i]) num=i;
}
dfs(num,-1,0);
for(int i=1;i<=n;i++)
{
big=max(big,dist[i]);
}
printf("%lld\n",10*big+(big*big+big)/2);
}