アルゴリズム導論-2.2-7-ツリーの直径
一、テーマ
ツリーT=(V,E)の直径(diameter)はmax(u,v)と定義され、すなわち、ツリーの直径は、ツリー内のすべての最短パス長の最大値である.ツリーの直径を計算する有効なアルゴリズムを書き出し,アルゴリズムの実行時間を解析した.
二、考える
Step 1:ツリー内の任意のノードをソースポイントとし、広さ優先遍歴を行い、ソースポイントから最も遠い点dを見つける
Step 2:dをソース点とし,広さ優先遍歴を行い,dから最も遠い点を探し出し,その長さを記録する
三、コード
ツリーT=(V,E)の直径(diameter)はmax(u,v)と定義され、すなわち、ツリーの直径は、ツリー内のすべての最短パス長の最大値である.ツリーの直径を計算する有効なアルゴリズムを書き出し,アルゴリズムの実行時間を解析した.
二、考える
Step 1:ツリー内の任意のノードをソースポイントとし、広さ優先遍歴を行い、ソースポイントから最も遠い点dを見つける
Step 2:dをソース点とし,広さ優先遍歴を行い,dから最も遠い点を探し出し,その長さを記録する
三、コード
//
#include <iostream>
#include <queue>
using namespace std;
#define N 8
#define WHITE 0
#define GRAY 1
//
struct Edge
{
int start;//
int end;//
Edge *next;//
Edge(int s, int e):start(s),end(e),next(NULL){}
};
//
struct Vertex
{
Edge *head;//
bool color;// ,
Vertex *p;//
int d;//
Vertex():head(NULL),color(WHITE),p(NULL),d(0x7fffffff){}
};
//
struct Graph
{
Vertex *V[N+1];//N
Graph()
{
int i;
for(i = 1; i <= N; i++)
V[i] = new Vertex;
}
~Graph()
{
int i;
for(i = 1; i <= N; i++)
delete V[i];
}
};
// STL
queue<Vertex*> Q;
//
void InsertEdge(Graph *G, Edge *E)
{
//
if(G->V[E->start]->head == NULL)
G->V[E->start]->head =E;
// , , ,
else
{
// ,
Edge *e1 = G->V[E->start]->head, *e2 = e1;
while(e1 && e1->end < E->end)
{
e2 = e1;
e1 = e1->next;
}
if(e1 && e1->end == E->end)
return;
if(e1 == e2)
{
E->next = e1;
G->V[E->start]->head =E;
}
else
{
e2->next = E;
E->next = e1;
}
}
}
// ,
void BFS(Graph *G, Vertex *s, int &ls, int &lv)
{
int i;
// , ,
for(i = 1; i <= N; i++)
{
G->V[i]->color = WHITE;
G->V[i]->d = 0x7fffffff;
G->V[i]->p = NULL;
}
// s
s->color = GRAY;
s->d = 0;
s->p = NULL;
// , s
while(!Q.empty())
Q.pop();
Q.push(s);
// ,
while(!Q.empty())
{
// u,
Vertex *u = Q.front();
Q.pop();
// u v
Edge *e = u->head;
while(e)
{
Vertex *v = G->V[e->end];
// v ,
if(v->color == WHITE)
{
//
v->color = GRAY;
//
v->d = u->d + 1;
if(v->d > ls)
{
ls = v->d;
lv = v->id;
}
//u
v->p = u;
//
Q.push(v);
}
e = e->next;
}
// u ,u ( , )
u->color = GRAY;
}
}
//
void Print(Graph *G)
{
int i;
//
for(i = 1; i <= N; i++)
{
cout<<i<<':';
// i
Edge *e = G->V[i]->head;
while(e)
{
cout<<e->end<<' ';
e = e->next;
}
cout<<endl;
}
cout<<endl;
}
/*
1 2
1 4
4 2
2 5
5 4
3 6
3 5
6 6
*/
/*
1 2
1 5
2 6
6 3
7 6
3 7
3 4
4 8
7 8
7 4
*/
int main()
{
//
Graph *G = new Graph;
Edge *E;
Print(G);
//
int i, start, end;
for(i = 1; i <= 10; i++)
{
cin>>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<<ls<<endl;
return 0;
}