天天看點

hiho#1050 : 樹中的最長路

#1050 : 樹中的最長路

10000ms

1000ms

256MB

描述

上回說到,小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

這道題和hdu2196簡單一些 求得是樹的最長路

首先假設樹的最長路的兩個葉子節點為v1,v2,那麼現有結論,從任意一點u出發走到的最遠的點一定是(v1,v2)中的一點,然後

再從v1或者v2出發走到的最遠點一定是v2或者v1。是以經過兩次搜尋就能找到最長路徑。

​​​​

AC代碼:

#include <stdio.h>
#include <vector>
#include <queue>
#include <algorithm>
#include <string.h>
using namespace std;
vector<int>tree[100005];
bool vis[100005];
int end_root,Max_len;
void dfs(int x,int len)
{
  vis[x]=true;
//  printf("x=%d len=%d\n",x,len);
  if(len>Max_len) Max_len=len,end_root=x;
  for(int i=0;i<tree[x].size();i++)
  {
    if(!vis[tree[x][i]])
    {
      dfs(tree[x][i],len+1);
    }
  } 
}
int main()
{
  int n;
  while(~scanf("%d",&n))
  {
    int max_val=0;
    memset(tree,0,sizeof(tree));
    for(int i=1;i<n;i++)
    {
      int a,b;
      scanf("%d %d",&a,&b);
      tree[a].push_back(b);
      tree[b].push_back(a);
      max_val=max(max(a,b),max_val);
    }
    Max_len=0;
    memset(vis,0,sizeof(vis));
    dfs(1,0);
    memset(vis,0,sizeof(vis));
    dfs(end_root,0);
    printf("%d\n",Max_len);
  }
}