演算法導論 22 2 7 樹的直徑

2021-06-08 08:17:48 字數 1525 閱讀 5991

樹t=(v,e)的直徑(diameter)定義為max(u,v),亦即,樹的直徑是樹中所有最短路徑長度中的最大值。試寫出計算樹的直徑的有效演算法,並分析演算法的執行時間。

step1:以樹中任意乙個結點為源點,進行一次廣度優先遍歷,找出離源點距離最遠的點d

step2:以d為源點,進行一次廣度優先遍歷,找出離d最遠的點,並記錄其長度

//用鄰接表實現圖的轉置

#include #include using namespace std;

#define n 8

#define white 0

#define gray 1

//邊結點結構

struct edge

};//頂點結點結構

struct vertex

};//圖結構

struct graph

~graph() };

//廣搜的先進先出用stl中的佇列來實現

queueq;

//插入邊

void insertedge(graph *g, edge *e)

if(e1 && e1->end == e->end)

return;

if(e1 == e2)

else

}}//在廣度優先搜尋的同時,記錄從離源點最遠的點及其長度

void bfs(graph *g, vertex *s, int &ls, int &lv)

//對s進行特殊的初始化

s->color = gray;

s->d = 0;

s->p = null;

//初始化佇列,使其僅含源頂點s

while(!q.empty())

q.pop();

q.push(s);

//只要佇列中還有灰色頂點,迴圈將一直進行下去

while(!q.empty())

//u被標記為該頂點的父母

v->p = u;

//將它置於佇列的尾部

q.push(v);

}e = e->next;

} //當u的鄰接表中的所有頂點被檢查完後,u被置為黑色(僅僅是便於理解,沒有實際意義)

u->color = gray; }}

//輸出

void print(graph *g)

cout<>start>>end;

e = new edge(start, end);

insertedge(g, e);

//無向圖,要加兩條邊

e = new edge(end, start);

insertedge(g, e);

} print(g);

int ls = -1, lv;

//第一次搜尋,從任意結點出發,找出最遠的點lv,lv一定是所求路徑上的乙個端點

bfs(g, g->v[1], ls, lv);

ls = -1;

//第二次搜尋,從lv出發,找出最長的路徑

bfs(g, g->v[lv], ls, lv);

cout<

演算法導論 22 2 7 樹的直徑

22.2 7 很顯然數的直徑就是樹的最長簡單路。先進行一次bfs 然後再從 bfs的終點再進行一次 bfs得到的最長路徑就是直徑。進行了兩次 bfs,所以複雜度還 o e v 參考自 樹的直徑是指樹的最長簡單路。求法 兩遍bfs 先任選乙個起點bfs找到最長路的終點,再從終點進行bfs,則第二次bf...

兩次BFS求樹的直徑 演算法導論22 2 7

以任意點w開始,先做一次bfs,找到最遠的點v,然後再以此點v進行一次bfs,找到最遠的點為u,u到v就是樹的直徑。此問題的關鍵不是在程式設計,而是要證明,網上也找了很多資料,沒有看到證明,以下是個人的證明方法。首先要知道樹是沒有環路的連通圖,任意兩點都有一條通路,而且也只有一條通路。同時假設樹的一...

演算法導論22 2 7

從任意起點開始,執行一次bfs,得到乙個最遠點d1,d1即為直徑的一點 再執行一次bfs,得到乙個最遠點d2,則d1 d2為樹的直徑 為什麼這樣是對的?1 證明d1是樹直徑的一點 a 若s在直徑d1,d2上,則最後乙個點必能搜到d1或d2 因為若搜到最後乙個點為v,則直徑為vd2,與題意不符 b 若...