樹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 若...