時間限制:1.0s 內存限制:256.0MB
問題描述
很久以前,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
5
1 2 2
1 3 1
2 4 5
2 5 4樣例輸出1
135
輸出格式
大臣J從城市4到城市5要花費135的路費。
解題思路
一棵樹,求任意兩點間的最大距離。 先以任意一點爲根,找到距離他最遠的點p,然後再以找到的這個點p爲根,找離p最遠的點q,p q間的距離即爲任意兩點間的距離的最大值。畫一棵樹一看就明白爲什麼了。
AC代碼
vector:
#include <bits/stdc++.h>
using namespace std;
struct Road {
int v,w;
Road(int vv,int ww) {
v = vv;
w = ww;
}
};
vector <Road > r[10001];
int dis[10001];
void dfs(int nw,int pre,int d)
{
int len = r[nw].size();
dis[nw] = d;
for(int i=0;i<len;i++) {
if(r[nw][i].v == pre)
continue;
dfs(r[nw][i].v,nw,d+r[nw][i].w);
}
}
int main()
{
int n;
scanf("%d",&n);
int t1,t2,t3;
for(int i=1;i<n;i++) {
scanf("%d %d %d",&t1,&t2,&t3);
r[t1].push_back(Road(t2,t3));
r[t2].push_back(Road(t1,t3));
}
memset(dis,0,sizeof dis);
dfs(1,-1,0); //以1爲root
int root = max_element(dis+1,dis+n+1) - dis;
memset(dis,0,sizeof dis);
dfs(root,-1,0);
int Max = *max_element(dis+1,dis+n+1);
printf("%lld",Max*10+Max*(1+Max)/2);
}
手寫鄰接表:
#include <bits/stdc++.h>
using namespace std;
struct Road {
int v,w;
}r[20010];
void Set(int k,int v,int w)
{
r[k].v = v;
r[k].w = w;
}
int first[10005],next[20005];
long long dis[10005];
void dfs(int nw,int pre,int d)
{
int NEXT = first[nw];
dis[nw] = d;
while(NEXT != -1 ) {
if(r[NEXT].v != pre) {
// dis[r[NEXT].v] = d+r[NEXT].w;
dfs(r[NEXT].v,nw,d+r[NEXT].w);
}
NEXT = next[NEXT];
}
}
int main()
{
int n;
scanf("%d",&n);
int k=0,t1,t2,t3;
memset(first,-1,sizeof first);
for(int i=1;i<n;i++) {
scanf("%d %d %d",&t1,&t2,&t3);
Set(k,t2,t3);
next[k] = first[t1];
first[t1] = k;
k++;
Set(k,t1,t3);
next[k] = first[t2];
first[t2] = k;
k++;
}
memset(dis,0,sizeof dis); //以1爲root
dfs(1,-1,0);
int root = max_element(dis+1,dis+n+1) - dis; //求距離1最遠的點號
memset(dis,0,sizeof dis);
dfs(root,-1,0);
int Max = *max_element(dis+1,dis+n+1);
printf("%lld",Max*10+Max*(1+Max)/2);
}