1. 程式人生 > >題解報告:hihoCoder #1050 : 樹中的最長路

題解報告:hihoCoder #1050 : 樹中的最長路

最長 \n hihocoder 100% 測試數據 問題 hihocode 行為 target

描述

上回說到,小Ho得到了一棵二叉樹玩具,這個玩具是由小球和木棍連接起來的,而在拆拼它的過程中,小Ho發現他不僅僅可以拼湊成一棵二叉樹!還可以拼湊成一棵多叉樹——好吧,其實就是更為平常的樹而已。

但是不管怎麽說,小Ho喜愛的玩具又升級換代了,於是他更加愛不釋手(其實說起來小球和木棍有什麽好玩的是吧= =)。小Ho手中的這棵玩具樹現在由N個小球和N-1根木棍拼湊而成,這N個小球都被小Ho標上了不同的數字,並且這些數字都是出於1..N的範圍之內,每根木棍都連接著兩個不同的小球,並且保證任意兩個小球間都不存在兩條不同的路徑可以互相到達。總而言之,是一個相當好玩的玩具啦!

但是小Hi瞧見小Ho這個樣子,覺得他這樣沈迷其中並不是一件好事,於是尋思著再找點問題讓他來思考思考——不過以小Hi的水準,自然是手到擒來啦!

於是這天食過早飯後,小Hi便對著又拿著樹玩具玩的不亦樂乎的小Ho道:“你說你天天玩這個東西,我就問你一個問題,看看你可否知道?”

“不好!”小Ho想都不想的拒絕了。

“那你就繼續玩吧,一會回國的時候我不叫上你了~”小Hi嚴肅道。

“誒!別別別,你說你說,我聽著呢。”一向習慣於開啟跟隨模式的小Ho忍不住了,馬上喊道。

小Hi滿意的點了點頭,隨即說道:“這才對嘛,我的問題很簡單,就是——你這棵樹中哪兩個結點之間的距離最長?當然,這裏的距離是指從一個結點走到另一個結點經過的木棍數。”。

“啊?”小Ho低頭看了看手裏的玩具樹,困惑了。

提示一:路總有折點,路徑也不例外!

輸入

每個測試點(輸入文件)有且僅有一組測試數據。

每組測試數據的第一行為一個整數N,意義如前文所述。

每組測試數據的第2~N行,每行分別描述一根木棍,其中第i+1行為兩個整數Ai,Bi,表示第i根木棍連接的兩個小球的編號。

對於20%的數據,滿足N<=10。

對於50%的數據,滿足N<=10^3。

對於100%的數據,滿足N<=10^5,1<=Ai<=N, 1<=Bi<=N

小Hi的Tip:那些用數組存儲樹邊的記得要開兩倍大小哦!

輸出

對於每組測試數據,輸出一個整數Ans,表示給出的這棵樹中距離最遠的兩個結點之間相隔的距離。

樣例輸入

8
1 2
1 3
1 4
4 5
3 6
6 7
7 8

樣例輸出

6
解題思路:

AC代碼一(129ms):兩次dfs。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+5;
 4 vector<int> vec[maxn<<1];
 5 int n,u,v,maxdep,maxvex;bool vis[maxn];
 6 void dfs(int x,int dep){
 7     vis[x]=true;
 8     int sz=vec[x].size();
 9     if(sz==1&&dep>maxdep){maxdep=dep;maxvex=x;}
10     for(int i=0;i<sz;++i)
11         if(!vis[vec[x][i]])dfs(vec[x][i],dep+1);
12 }
13 int main(){
14     while(~scanf("%d",&n)){
15         for(int i=1;i<=n;++i)vec[i].clear();
16         while(--n){
17             scanf("%d%d",&u,&v);
18             vec[u].push_back(v);
19             vec[v].push_back(u);
20         }
21         maxdep=0,maxvex=1;
22         memset(vis,false,sizeof(vis));
23         dfs(1,0);
24         memset(vis,false,sizeof(vis));maxdep=0;
25         dfs(maxvex,0);
26         printf("%d\n",maxdep);
27     }
28     return 0;
29 }

AC代碼二(119ms):一次dfs。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+5;
 4 vector<int> vec[maxn];
 5 int n,u,v,ans;bool vis[maxn];
 6 int dfs(int u){
 7     vis[u]=true;
 8     int Dmax=0,Dsec=0;
 9     for(size_t i=0;i<vec[u].size();++i){
10         int x=vec[u][i];
11         if(vis[x])continue;
12         int nowd=dfs(x)+1;
13         if(nowd>Dmax)Dsec=Dmax,Dmax=nowd;
14         else if(nowd>Dsec)Dsec=nowd;
15     }
16     ans=max(ans,Dmax+Dsec);
17     return Dmax;
18 }
19 int main(){
20     while(~scanf("%d",&n)){
21         for(int i=1;i<=n;++i)vec[i].clear();
22         while(--n){
23             scanf("%d%d",&u,&v);
24             vec[u].push_back(v);
25             vec[v].push_back(u);
26         }
27         memset(vis,false,sizeof(vis));
28         ans=0;dfs(1);
29         printf("%d\n",ans);
30     }
31     return 0;
32 }

題解報告:hihoCoder #1050 : 樹中的最長路