試題 歷屆試題 大臣的旅費(求樹的直徑,兩次dfs)
阿新 • • 發佈:2020-08-03
問題描述
1 2 2
1 3 1
2 4 5
2 5 4 樣例輸出1 135 輸出格式
很久以前,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 51 2 2
1 3 1
2 4 5
2 5 4 樣例輸出1 135 輸出格式
大臣J從城市4到城市5要花費135的路費。
題解:求兩點間的最長路,剛開始每個點去暴搜,很自然地t了。 後來看了網上一些資料才知道是進行兩次dfs,第一次dfs任意一個頂點出發到的最遠的點即是直徑的一端, 記錄這個端點去找最遠的路徑,即是樹的直徑,也就是本題要找的最長路。 比如樣例從1出發最遠的點是4,從2出發最遠的點是4,從3出發最遠的點是4,從4出發最遠的點是5,從5出發最遠的點是4.
無論哪個點出發得到的最遠點都是直徑的端點。得到端點後再進行dfs,即是最遠的路徑。
code:
#include<bits/stdc++.h> using namespace std; int maxx=-1; const int maxn=1e6; vector<pair<int,int> >dis[maxn]; int vis[maxn]; int pos; void dfs(int m,int cost){ if(cost>maxx){ maxx=cost; pos=m; } for(int i=0;i<dis[m].size();i++){ if(!vis[dis[m][i].first]){ vis[dis[m][i].first]=1; dfs(dis[m][i].first,cost+dis[m][i].second); vis[dis[m][i].first]=0; } } } int main(){ int n,a,b,t;cin>>n; for(int i=0;i<n-1;i++){ scanf("%d%d%d",&a,&b,&t); dis[a].push_back(make_pair(b,t)); dis[b].push_back(make_pair(a,t)); } vis[1]=1; dfs(1,0); fill(vis,vis+maxn,0); vis[pos]=1; maxx=-1; dfs(pos,0); long long int sum=0; for(int i=1;i<=maxx;i++){ sum+=10+i; } cout<<sum<<endl; return 0; }