Вы находитесь на странице: 1из 70

Graph Theory

Author: chuong3a, nick yahoo: chuong3a

Undirected Graph .........................................................................................................2


Directed Graph .............................................................................................................4
Minimal Spanning Tree.................................................................................................6
Weight Matrix..............................................................................................................10
The types of Graph......................................................................................................10
Prims Algorithm .........................................................................................................17
Prim Algorithm code C++ with Notation ...................................................................19
Code Maple Prims.......................................................................................................20
Kruskal Algorithm Code C++ 1..................................................................................23
Kruskal Algorithm Code C++ 2..................................................................................25
Code Maple Kruskal....................................................................................................27
Depth First Search ......................................................................................................29
Code Maple DFS ........................................................................................................30
Depth First Search Algorithm......................................................................................31
Breadth First Search Algorithm ..................................................................................33
BFS Code Maple.........................................................................................................34
BFS Code C++............................................................................................................35
Dijkstra Algorithm ......................................................................................................37
Code Dijkstra Algorithm.............................................................................................37
Code Maple Dijsktra ...................................................................................................40
Dijkstra Algorithm run by hand ..................................................................................41
Bellman-Ford Algorithm.............................................................................................45
BellmanFord Code 2....................................................................................................47
Bellman-Ford run by hand .........................................................................................48
Floyd Code..................................................................................................................50
Code Maple Floyd 1....................................................................................................52
Code Maple Floyd 2....................................................................................................52
Chu trnh Euler............................................................................................................53
Euler Cycle Maple Code 1 ..........................................................................................54
1

Euler Cycle Maple Code 2 ..........................................................................................55


Stack: ..........................................................................................................................56
Euler Cycle C++ Code ................................................................................................57
Chu trnh Hamilton......................................................................................................59
Hamilton Maple Code.................................................................................................60
Code Hamilton C++....................................................................................................62
Dijsktra 2.....................................................................................................................67

1/ 4 ngi bt k trong s n > 3 ngi u quen vi 3 ngi cn li. CM rng lun c


1 ngi quen vi n 1 ngi cn li.
Solution:
- Gi s bi ton ng vi n = k, ngha l c 1 nh A ni vi k 1 nh cn li. Ta
cm bi ton ng vi n = k + 1.
- Gi s nh mi thm vo l nh B. Xt tp hp 4 nh A, B v 2 nh C, D t
th.
A ni vi C v D, nu A ni vi B th A ni vi k nh. Bi ton gii quyt xong.
- Nu A ko ni vi B th C s ni vi A, B, D. C nh C v thay D bng cc nh
D1, D2, D3 trong th. V trong tp 4 nh bt k lun c 1 nh ni vi 3 nh cn
li nn C s ni vi cc nh A, B, D1, D2,... vy C l nh ni vi k nh cn li.
2/ Trong gii c tng quc gia (c 20 k th) hin c 21 trn u c tin hnh.
CMR c mt k th thi u t nht 3 trn.
Solution:
- Cho s k th l l s nh ca 1 th, s trn u l s cnh ca th = m.
- Tng s bc ca cc nh = 2*m = 42. V c 20 k th nn nu ko c nh no c
bc 3 th ch c 2*20 = 40 cnh (tri gi thit). Vy phi c 2 nh bc 3 c t nht
2 k th thi u 3 trn.

Undirected Graph
- The AddEdge command adds one or more edges to an undirected graph. By
default, the original graph is changed to a graph containing the specified set of
edge(s). Theo default, th ban u s thay i thnh th mi cha tp cc cnh
thm vo. By setting inplace = false the original graph remains unchanged. Bng thit
lp inplace = false, th ban u s ko thay i.

- If the graph is weighted, then a weighted edge can be added by calling AddEdge
with one or more edges in the form [edge, weight], where the edge is just the set of
two vertices (nh), and the weight represents (i din) the value of the edge weight.
> with( GraphTheory):
G := CycleGraph(5):
AddEdge( G, {{1, 3}, {2, 4}}, inplace = true);
DrawGraph(G);
Graph G: an undirected unweighted graph with 5 vertices and 7 edge(s)

> with( GraphTheory):


G := Graph( Matrix( [ [0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 0], [0, 1, 0, 0] ] ), 'weighted');
Edges( G, weights);
DrawGraph(G);
0, 1, 1, 0
1, 0, 0, 1
1, 0, 0, 0
0, 1, 0, 0
Graph G: an undirected weighted graph with 4 vertices and 3 edge(s)
[{1, 2}, 1], [{1, 3}, 1], [{2, 4}, 1]

> AddEdge( G, [{1, 4}, 2]);


Edges( G, weights);
DrawGraph(G);
> G := Graph( [a, b, c, d] );
AddEdge( G, Trail( a, b, c, d, a ) );
DrawGraph(G);

AdjacencyMatrix(G);
0 1 0 1
1 0 1 0

0 1 0 1
1 0 1 0

Directed Graph
1/ > with( GraphTheory):
G := Digraph( [a, b, c, d, e], {[a, b], [b, c], [c, d], [d, e]} );
4

DrawGraph(G);

AddArc( G, {[a, c], [b, d]} );


DrawGraph(G);
2/ > with( GraphTheory):
G := Graph( Matrix( [ [0, 1, 1, 0], [1, 0, 0, 3], [0$4] $2] ), 'weighted', 'directed');
DrawGraph(G);
4/ > with( GraphTheory):
G := Digraph( [1, 2, 3, 4], Trail( 1, 2, 3, 4, 1) );
DrawGraph(G);
AdjacencyMatrix(G);

0
0

0
1

1
0
0
0

0
1
0
0

0
0

1
0

Minimal Spanning Tree


GraphTheory [KruskalsAlgorithm]
GraphTheory [PrimsAlgorithm]
- Calling Sequence:
MinimalSpanningTree(G)
MinimalSpanningTree(G, w, animate)
KruskalsAlgorithm(G, w, animate)
PrimsAlgorithm(G, w, animate)
Parameters:
G: an undirected graph, weighted or unweighted
w: (optional) name
animate: (optional) literal animate (theo ngha ca nh ng) indicating (cho bit)
that an animation of the algorithm should be returned instead of the tree.
Description
- MinimalSpanningTree, KruskalsAlgorithm, and PrimsAlgorithm all return a
spanning tree of the undirected graph G with minimum possible weight. If the graph
G is unweighted, each edge is considered to have weight 1.
- If the optional parameter w is given, it is assigned (c gn cho) the weight of
the minimal spanning tree.
- If the literal animate, or animate = true is given, an animation of the application
of the algorithm will be returned instead of the minimal spanning tree. Nu c ch
animate or animate = true, 1 nh ng ca thut ton s cho kt qu thay cho cy
khung ti thiu.
> with( GraphTheory ):
with( RandomGraphs ):
A := Matrix( [ [0, 1, 0, 4, 0, 0], [1, 0, 1, 0, 4, 0], [0, 1, 0, 3, 0, 1], [4, 0, 3, 0, 1, 0], [0,
4, 0, 1, 0, 4], [0, 0, 1, 0, 4, 0] ]):
G := Graph(A):
DrawGraph(G);

1
2
3
4
5
6

1
0
1
0
4
0
0

2
1
0
1
0
4
0

3
0
1
0
3
0
1

4
4
0
3
0
1
0

5
0
4
0
1
0
4

6
0
0
1
0
4
0

T := MinimalSpanningTree(G);
DrawGraph(T);

1 2; 2 3; 3 4; 3 6; 4 5;
Edges(T, weights);
{ [{1, 2}, 1], [{2, 3}, 1], [{3, 4}, 3], [{3, 6}, 1], [{4, 5}, 1] }
PrimsAlgorithm( G, 'w', animate);
w;

KruskalsAlgorithm( G, 'w', animate);


w;
Dijkstras Algorithm
Calling Sequence
DijkstrasAlgorithm(G, s, t)
DijkstrasAlgorithm(G, s, T)
DijkstrasAlgorithm(G, s)
Parameters
- G: a graph with nonnegative edge weights or no weights
- s, t: vertices of the graph G
- T: list of vertices of the graph G
Description
- If G is an unweighted graph, the edges are assumed all to have weight 1.
- If G is a weighted graph, DijkstrasAlgorithm(G, s, t) returns the cheapest
weighted path from vertex s to vertex t in the graph G. If a path from s to t exists, the
output is a list of the form [[s,...,t], w] where [s,...,t] is the path and w is the weight of
that path. If no such path exists the output is
.
- In the second calling sequence where T is a list of vertices of G, this is short for
[seq(DijkstrasAlgorithm(G, s, t), t = T)], save that the algorithm does not need to
recompute cheapest paths.
- In the third calling sequence where no destination vertices (im ch) are given,
this is short for DijkstrasAlgorithm(G, s, Vertices(G)), i.e. the cheapest path from s to
every vertex in G is output.
- To compute distances between all pairs of vertices simultaneously (ng thi),
use the AllPairsDistance command. To ignore edge weights (and use a faster breadthfirst search) use the ShortestPath command.
- If some edge weights are negative, the BellmanFordAlgorithm command can be
used to compute the shortest path.

> with( GraphTheory ):


G := Graph( { [{1, 2}, 1], [{2, 3}, 3], [{3, 4}, 7], [{4, 5}, 8], [{5, 6}, 15],
[{1, 6}, 11] } );
DijkstrasAlgorithm( G, 1, 4);
DrawGraph(G);

WeightMatrix(G)
> G := Graph( { [{1, 2}, 1], [{2, 3}, 3], [{3, 4}, 7], [{2, 4}, 2], [{4, 1}, 15] } );
DijkstrasAlgorithm( G, 1, 4);
DrawGraph(G);

[ [1, 2, 4], 3 ]
> WeightMatrix(G)
0
1
0

1
0
3

0
3
0
9

15
2
7

15

x1[16] = { 0, 1, 0, 15, 1, 0, 3, 2, 0, 3, 0, 7, 15, 2, 7, 0 };


Weight Matrix
Calling Sequence
WeightMatrix(G, cp)
Parameters
G: weighted graph
cp: (optional) symbol or equation
Description
- WeightMatrix returns the matrix of edge weights of a weighted graph. The
optional argument cp is used to control whether the weight matrix of the graph or a
copy of it should be returned. The argument cp can be either the symbol copy or an
equation of the form copy=true or copy=false. If the argument is missing the
command returns a copy of the weight matrix of the graph by default.
The types of Graph
Cho G = (X, E) l th ko hng.
a/ G gi l k-u nu d(i) = k, vi mi I thuc X.
b/ G gi l lng phn nu X c th phn hoch thnh X1, X2 sao cho mi cnh
ca G u ni 1 nh trong X1 vi 1 nh trong X2 v vit l G = (X1, X2, E)
- Nu G n v mi nh trong X1 u ni vi tt c cc nh trong X2 th G gi l
th lng phn , k hiu l K(r, s), vi r = s nh ca X1 = |X1|, s = s nh ca
X2 = |X2|. c bit, K(1, s) gi l th 1 ngi sao.
c/ G gi l 1 bnh xe nu G c n 1 nh v n 1 cnh to thnh 1 a gic u, v
tt c cc nh u ni vi tm ca a gic. K hiu Wn.
> with(GraphTheory):
with(SpecialGraphs):
G := GeneralizedPetersenGraph(5, 2);
DrawGraph(G);

10

> DegreeSequence(G);
with(networks)
V th K5.
> G := CycleGraph(5);
DrawGraph(G);

AddEdge( G, { {1, 3}, {1, 4}, {2, 4}, {2, 5}, {3, 1}, {3, 5}, {4, 1}, {4, 5} } );
DrawGraph(G);
> with(GraphTheory):
G := Graph( [1, 2, 3, 4, 5]);
for i from 1 to 5 do
for j from 1 to 5 do
if (i != j) then
AddEdge( G, {i, j});
end if;
end do;
11

end do;
DrawGraph(G);

th K5.
AdjacencyMatrix(G);
1
2
3
4
5

1
0
1
1
1
1

2
1
0
1
1
1

3
1
1
0
1
1

4
1
1
1
0
1

5
1
1
1
1
0

DijkstrasAlgorithm( G, 1 );
V th K6
G := Graph( [1, 2, 3, 4, 5, 6]);
DrawGraph(G);
for i from 1 to 6 do
for j from 1 to 6 do
if (i != j) then
AddEdge( G, {i, j});
end if;
end do;
end do;
DrawGraph(G);

12

G := Graph( [1, 2, 3, 4, 5, 6]);


for i from 1 to 6 do
for j from 1 to 6 do
if (i != j and j != i+3) then
AddEdge( G, {i, j});
end if;
end do;
end do;
DeleteEdge( G, { {1, 4}, {2, 5}, {3, 6} });
DrawGraph(G);

AdjacencyMatrix(G);
1
2
3
4

1
0
1
1
0

2
1
0
1
1

3
1
1
0
1

4
0
1
1
0

5
1
0
1
1

6
1
1
0
1
13

5
6

1
1

0
1

1
0

1
1

0
1

1
0

int *x, n, i, j; n = 6; x = new int [37];


for (i = 1; i <= n; i++)
for (j = 1; j <= n; i++)
x[i][j] = 1;
for (i = 1; i <= 3; i++)
for (j = 4; j <= 6; j++)
if (j == i+3)
x[i][j] = 0;

V th K(3, 4)
G := Graph( [1, 2, 3, 4, 5, 6, 7]);
for i from 1 to 3 do
for j from 4 to 7 do
if (i != j) then
AddEdge( G, {i, j});
end if;
end do;
end do;
DrawGraph(G);

V th W6
G := Graph( [1, 2, 3, 4, 5, 6], Trail(1, 2, 3, 4, 5, 1) );
for i from 1 to 5 do
AddEdge( G, {i, 6});
end do;
14

DrawGraph(G);

DijkstrasAlgorithm( G, 1 );
> with(GraphTheory):
with(SpecialGraphs):
G := GeneralizedPetersenGraph(5, 2);
DrawGraph(G);

> with(GraphTheory):
with(SpecialGraphs):
G := GeneralizedPetersenGraph(6, 2);
DrawGraph(G);

15

> with(GraphTheory):
with(SpecialGraphs):
G := GeneralizedPetersenGraph(7, 2);
DrawGraph(G);

> with(GraphTheory):
with(SpecialGraphs):
G := WheelGraph(6);
DrawGraph(G);

16

Prims Algorithm
Tm cy khung c trng s nh nht.
> with(GraphTheory):
G := Graph( { [{1, 2}, 1], [{1, 3}, 1], [{1, 4}, 1], [{1, 5}, 1], [{2, 3}, 1], [{2, 4}, 1],
[{2, 5}, 1], [{3, 4}, 1], [{3, 5}, 1], [{4, 5}, 1] } );
DrawGraph(G);

PrimsAlgorithm(G);

> with(GraphTheory):

17

G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4},
6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );
DrawGraph(G);

PrimsAlgorithm(G, 'w', animate);

Edge (1, 2): 3


Edge (2, 3): 5
Edge (2, 4): 6
Edge (1, 5): 16
KruskalsAlgorithm(G, 'w', animate);
WeightMatrix(G);
1
2
3
4

1
0
3
24
35

2
3
0
5
6

3
24
5
0
7

4
35
6
7
0

5
16
17
38
19
18

16

17

38

19

x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 }


x1[] = { 0, 3, 24, 35, 16, 3, 0, 5, 6, 17, 24, 5, 0, 7, 38, 35, 6, 7, 0, 19, 16, 17, 38, 19,
0 };
x1[] = { 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0 };
Prim Algorithm code C++ with Notation
#include <iostream.h>
#include <stdio.h>
class Prim {
int n, k;
int visited[10], min, minicost, A[10][10];
public:
Prim() {
k = 1; // Number of Edges
minicost = 0; }
void Read();
void Prims1 (int cost[][10], int n);
};
void Prim :: Read() {
n = 5; int i, j, k1; k1 = 0;
int x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 };
for (i = 1; i <= n; i++) {
for (j = i+1; j <= n; j++) {
A[i][j] = x1[k1]; k1++;
printf ("A[%d][%d] = %d ", i, j, A[i][j]);
} printf ("\n");
} Prims1 (A, n);
}
void Prim :: Prims1 (int A[][10], int n) {
int i, j, a, b, b1[n], b2[n], b3[n], k1; k1 = 0;
for (i = 2; i <= n; i++)
visited[i] = 0;
cout << "\n Edges in the spanning tree are: \n";
visited[1] = 1;
while (k < n) {
printf ("k = %d \n", k);
for (i = 1, min = 999; i <= n; i++)
for (j = i+1; j <= n; j++)
//printf ("\n i = %d, j = %d \n", i, j);
if (A[i][j] > min) {
printf ("if A[%d][%d] = %d > min = %d continue \n", i, j, A[i][j], min);
}
19

else if (A[i][j] < min) {


printf ("if A[%d][%d] = %d < min = %d \n", i, j, A[i][j], min);
if (visited[i] == 0) {
printf ("if (visited[%d] == %d) continue \n", i, visited[i]);
continue;
}
else {
min = A[i][j]; a = i; b = j;
printf ("min = A[%d][%d] = %d \n", i, j, min);
//printf ("a = i = %d, b = j = %d \n", i, j);
} }
if (visited[a] == 0 || visited[b] == 0) {
printf ("\n if (visited[a] = visited[%d] == %d) \n", a, visited[a]);
printf ("or if (visited[b] = visited[%d] == %d) \n", b, visited[b]);
k++; printf ("k++ = %d \n", k);
printf ("Edge(%d, %d): %d \n", a, b, min);
b1[k1] = a; b2[k1] = b; b3[k1] = min; k1++;
minicost += min; visited[b] = 1;
printf ("visited[b] = visited[%d] = 1 \n", b);
} A[a][b] = A[b][a] = 999;
printf ("A[%d][%d] = A[%d][%d] = 999 \n", a, b, b, a);
printf ("min = %d \n", min);
} cout << "\n Minimum cost spanning tree is:" << minicost;
printf ("The Spanning Tree \n");
for (i = 0; i < n-1; i++)
printf ("Edge (%d, %d): %d \n", b1[i], b2[i], b3[i]);
}
int main() {
cout << "\n Prim's algorithm \n";
Prim p; p.Read();
}
Code Maple Prims
Prims := proc(G::Graph, x0)
local n, A, Kt, i, j, t, min, a, b, T;
min := 999; A := WeightMatrix(G); n := NumberOfVertices(G);
Kt := {x0}; T := Graph(n);
if not IsConnected(G) then
return ("Do thi nay ko lien thong");
end if;
for t from 1 to n-1 do
min := 999;
for i in Kt do
for j from 1 to n do
if 0 < A(i, j) < min and j Kt then
20

min := A(i, j); a := i; b := j;


end if;
end do;
end do;
Kt := Kt union {b};
T := AddEdge(T, {a, b});
end do;
return T;
end proc:
with(GraphTheory):
with(RandomGraphs):
G := RandomGraph( 8, 10, connected, weights = 1..10);
T := Prims(G, 1);
HighlightEdges(G, T, red);
DrawGraph(G);
with(GraphTheory):
G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4},
6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );
DrawGraph(G);
C := Edges( G, weights);
C = { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4}, 6], [{2,
5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] }
for y in C do
print( y[1][1], y[1][2], y[1], y[2]);
end do;
y[1][1] = 1; y[1][2] = 2; y[1] = {1, 2}; y[2] = 3;
y[1][1] = 1; y[1][2] = 3; y[1] = {1, 3}; y[2] = 24;
for y in C do
if y[1] = {1, 3} then
print(y[2]); end if;
end do;
y[2] = 24.
if (i[1][1]=x1 and i[1][12] = x2) or (i[1][2]=x1 and i[1][1]=x2)
for i in Edges(G,weights)
if( y[1] = {x1, x2} or y[1] = {x2, x1} )
y[1][2] lc chnh l trng lng
21

Gii thut:
- Step 1: Chn ty nh x 0 X v khi to V := { x0 } , T : = , V l tp nh, T
l tp cnh.
- Step 2: Trong s nhng cnh ni nh x0 vi y m x 0 V and y X \ V , ta chn
cnh e c trng s nh nht. Nu ko c cnh e: Dng (1).
- Step 3: Gn V := V {y}, and T := T {e}.
- Step 4: Nu T n-1 phn t th Dng (2), ngc li lm tip bc 2.
Ghi ch: Khi thut ton dng theo trng hp 1 (Tm ko c cnh t x i ra) th th
ko lin thng nn ko c cy khung.
> with(GraphTheory):
G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4},
6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );
DrawGraph(G);

Prim Algorithm
- Step 1: chn nh 1, trong s nhng cnh k vi nh 1, chn cnh {1, 2} c
trng s min l 3.
- Step 2: chn nh 2, trong s nhng cnh k vi nh 1, 2, chn cnh {2, 3} c
trng s min l 5.
- Step 3: trong s nhng cnh k vi nh 1, 2, 3 chn cnh {2, 4} c trng s min
l 6.
- Step 4: trong s nhng cnh k vi nh 1, 2, 3, 4 chn cnh {3, 4} c trng s
min l 7. {2, 3, 4} to thnh chu trnh nn b cnh {3, 4}.
- Step 5: trong s nhng cnh k vi nh 1, 2, 3, 4, chn cnh {1, 5} c trng s
min l 16.
Kruskal Algorithm
- Step 1: chn cnh {1, 2} c trng s min l 3.
- Step 2: chn cnh {2, 3} c trng s min l 5.

22

- Step 3: chn cnh {2, 4} c trng s min l 6.


- Step 4: chn cnh {3, 4} c trng s min l 7. Nhng {2, 3, 4} to thnh chu trnh
nn b cnh {3, 4}.
- Step 5: chn cnh {1, 5} c trng s min l 16.
Kruskal Algorithm Code C++ 1
Step 1: Sp xp cc cnh ca th theo th t trng s tng dn v khi to cy T =

Step 2: Duyt theo cnh e thuc danh sch sp xp. Nu T + e ko cha chu trnh
th:
Ghp cy e vo cy: T = T + {e};
Nu T n 1 phn t th dng.
#include <iostream.h>
#include <stdio.h>
#define MAX 100
class Kruskal {
private:
struct Edge1 {
int u, v, weight;
} Edge[MAX];
int Tree[MAX][2], set[MAX]; int n;
public:
int ReadEdges();
void MakeSet();
int Find (int vertex);
void Join (int v1, int v2);
void Arrange (int k);
int SpanningTree (int k);
void Display (int k);
};
int Kruskal :: ReadEdges() {
int i, j, k, m; k = 1; n = 5; m = 0;
int x[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 };
for (i = 1; i <= n; i++)
for (j = i+1; j <= n; j++) {
Edge[k].u = i; Edge[k].v = j;
Edge[k++].weight = x[m]; m++;
}
return (k - 1);
}
void Kruskal :: MakeSet() {
int i;
for (i = 1; i <= n; i++)
23

set[i] = i;
}
int Kruskal :: Find (int vertex) {
return (set[vertex]);
}
void Kruskal :: Join (int v1, int v2) {
int i, j;
if (v1 < v2) {
printf ("if (v1 = %d < v2 = %d) \n", v1, v2);
printf ("set [v2] = v1; set[%d] = %d \n", v2, v1);
set[v2] = v1; }
else {
printf ("if (v1 = %d > v2 = %d) \n", v1, v2);
printf ("set[v1] = v2; set[%d] = %d \n", v1, v2);
set[v1] = v2; }
}
void Kruskal :: Arrange (int k) {
int i, j;
struct Edge1 temp;
for (i = 1; i < k; i++)
for (j = 1; j <= k - i; j++)
if (Edge[j].weight > Edge[j + 1].weight) {
temp = Edge[j];
Edge[j] = Edge[j + 1];
Edge[j + 1] = temp;
}
}
int Kruskal :: SpanningTree (int k) {
int i, t, j, sum, k1, k2; Arrange(k); t = 1; sum = 0;
for (i = 1; i <= k; i++)
printf ("Edge (%d, %d): %d \n", Edge[i].u, Edge[i].v, Edge[i].weight);
for (i = 1; i <= n; i++)
if (Find (Edge[i].u) != Find (Edge[i].v)) {
for (j = 1; j <= n; j++)
printf ("set[%d] = %d ", j, set[j]);
k1 = Edge[i].u; k2 = Edge[i].v;
printf ("\n if (Find (Edge[%d].u) != Find (Edge[%d].v)) \n", i, i);
printf (" Find(%d) = set [%d] = %d \n", k1, k1, set[k1]);
printf (" Find(%d) = set [%d] = %d \n", k2, k2, set[k2]);
Tree[t][1] = Edge[i].u;
Tree[t][2] = Edge[i].v;
printf ("Tree[%d][1] = Edge[%d].u = %d \n", t, i, Edge[i].u);
printf ("Tree[%d][1] = Edge[%d].v = %d \n", t, i, Edge[i].v);
sum += Edge[i].weight;
printf ("Join (Edge[%d].u, Edge[%d].v); t++ = %d; \n\n", t, t, t+1);
24

Join (Edge[t].u, Edge[t].v); t++;


}
else {
printf ("if (Find (Edge[%d].u) == Find (Edge[%d].v)) continue \n", i, i);
printf ("Edge[%d].u = %d, Edge[%d].v = %d \n", i, Edge[i].u, i, Edge[i].v);
continue; }
return sum;
}
void Kruskal :: Display (int k) {
int i;
cout << "\n The Edges of the Minimum Spanning Tree are \n ";
for (i = 1; i < n; i++)
cout << Tree[i][1] << " - " << Tree[i][2] << endl;
cout << "\n The Cost of the Minimum Spanning Tree is : " << k;
}
int main() {
int ecount, totalcost; Kruskal k;
ecount = k.ReadEdges(); k.MakeSet();
totalcost = k.SpanningTree (ecount);
k.Display (totalcost);
return 0;
}
Kruskal Algorithm Code C++ 2
#include <iostream.h>
#include <stdio.h>
class Kruskal {
private:
int n; // number of nodes
int noe; //no edges in the graph
int graph [100][4];
int sets[10];
int k2;
public:
void ReadGraph();
void Initial();
void SortEdges();
void Algorithm();
int FindNode(int k);
void print();
};
void Kruskal :: ReadGraph() {
int i, j, k, w; n = 5; noe = 0; k = 0;
25

int x[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 };


for (i = 1; i <= n; i++) {
for (j = i+1; j <= n; j++) {
if (x[k] != 0) {
noe++; graph [noe][1] = i;
graph [noe][2] = j; graph [noe][3] = x[k]; k++;
} } }
// print the graph edges
cout << "\n The edges in the given graph are:: \n";
for (i = 1; i <= noe; i++)
cout << " < " << graph [i][1] << " , " << graph [i][2]
<< " > ::" << graph [i][3] << endl;
}
void Kruskal :: SortEdges() {
/* Sort the edges using bubble sort in increasing order */
int i, j;
for (i = 1; i <= noe-1; i++) {
for (j = 1; j <= noe-i; j++) {
if (graph [j][3] > graph [j+1][3]) {
int t = graph [j][1];
graph [j][1] = graph [j+1][1];
graph [j+1][1] = t; t = graph [j][2];
graph [j][2] = graph [j+1][2];
graph [j+1][2] = t; t = graph [j][3];
graph [j][3] = graph [j+1][3];
graph [j+1][3] = t;
} } }
// print the graph edges
cout << "\n After sorting the edges in the given graph are:: \n";
for (i = 1; i <= noe; i++)
cout << " < " << graph [i][1] << " , " << graph [i][2]
<< " > ::" << graph [i][3] << endl;
}
void Kruskal :: Algorithm() {
int i, j, k1, p1, p2; k2 = 1;
// ->make a set for each node
for (i = 1; i <= n; i++) {
sets[i] = i;
} cout << "\n The algorithm starts :: \n";
for (i = 1; i <= n; i++) {
printf ("p1 = FindNode (graph[%d][1] = %d) \n", i, graph [i][1]);
p1 = FindNode (graph [i][1]);
printf ("p1 = %d \n", p1);
printf ("p2 = FindNode (graph[%d][2] = %d) \n", i, graph [i][2]);
p2 = FindNode (graph [i][2]);
26

printf ("p2 = %d \n", p2);


if (p1 != p2) {
cout << "The edge included in the tree is :: "
<< " < " << graph [i][1] << " , "
<< graph [i][2] << " > " << endl;
k2++;
} /* End if (p1 != p2) */
else {
cout << "Inclusion of the edge " << " < " << graph [i][1] << " , "
<< graph [i][2] << " > " << "forms a cycle so it is removed \n";
}
} /* End for (i = 1; i <= noe; i++) */
}
int Kruskal :: FindNode (int n) {
for (int i = 1; i <= k2; i++) {
if (n == sets[i]) {
printf ("if (%d == sets[%d] = %d) \n", n, i, sets[i]);
printf ("return 1 \n");
return 1;
}
else {
printf ("if (%d != sets[%d] = %d) \n", n, i, sets[i]);
printf ("return -1 \n");
}
} return -1;
}
int main() {
Kruskal obj; obj.ReadGraph();
obj.SortEdges(); obj.Algorithm();
return 0;
}
Code Maple Kruskal
with(GraphTheory):
G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4},
6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );
DrawGraph(G);
Kruskal := proc(G::Graph)
local n, A, i, j, k, t, min, il, jl, T, Mien, tam;
min := 999;
A := WeightMatrix(G); n := NumberOfVertices(G);
Mien := array(1..n): T := Graph(n);
if not IsConnected(G) then
27

return ("Do thi nay ko lien thong");


end if;
for i from 1 to n do
Mien[i] := i;
end do;
for t from 1 to n-1 do
min := 999;
for i from 1 to n-1 do
for j from 1 to n do
if 0 < A[i, j] < min and Mien[i] != Mien[j] then
min := A[i, j]; il := i; jl := j;
end if;
end do;
end do;
T := AddEdge(T, {il, jl} );
Mien[jl] := Mien[il];
end do;
return T;
end proc:
with(GraphTheory):
with(RandomGraphs):
G := RandomGraph( 8, 10, connected, weights = 1..10);
T := Kruskal(G, 1);
HighlightEdges(G, T, red);
DrawGraph(G);
Code 2:
Kruskal := proc(G::Graph)
local n, A, i, j, k, t, min, il, jl, T, Mien, tam, Kt;
min := 999; Kt := { };
A := WeightMatrix(G); n := NumberOfVertices(G);
Mien := array(1..n): T := Graph();
if not IsConnected(G) then
return ("Do thi nay ko lien thong");
end if;
for i from 1 to n do
Mien[i] := i;
end do;
for t from 1 to n-1 do
min := 999;
for i from 1 to n do
for j from 1 to n do
if 0 < A[i, j] < min and Mien[i] != Mien[j] then
28

min := A[i, j]; il := i; jl := j;


end if;
end do;
end do;
if il Kt then T := AddVertex(T, il); Kt := Kt union {il}; end if;
if jl Kt then T := AddVertex(T, jl); Kt := Kt union {jl}; end if;
T := AddEdge(T, {il, jl} );
Mien[jl] := Mien[il];
end do;
return T;
end proc:
with(GraphTheory):
with(RandomGraphs):
G := RandomGraph( 8, 10, connected, weights = 1..10);
T := Kruskal(G, 1);
HighlightEdges(G, T, red);
DrawGraph(G);

Depth First Search


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define MAX 20
int A[MAX][MAX];
int v[MAX];
int i = 1, n; int T[20];
void DFS (int v1) {
int v2; cout << v1 << "\t"; v[v1] = 1;
printf ("v[%d] = 1 \n", v1);
for (v2 = 1; v2 <= n; v2++)
if (A[v1][v2] != 0 && v[v2] == 0) {
printf ("if (A[%d][%d] == 1 && v[%d] == 0) \n", v1, v2, v2);
printf ("%d - %d \n", v1 , v2);
printf ("DFS (%d) \n", v2);
T[i] = v1; T[i+1] = v2; i = i + 2;
DFS (v2);
}
}
void Create() {
n = 9; int i, j, k1; k1 = 0;
29

int x1[] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0};
for (i = 1; i <= n; i++)
for (j = i+1; j <= n; j++) {
A[j][i] = A[i][j] = x1[k1]; k1++;
}
for (i = 1; i <= n; i++) {
j = i; A[i][j] = 0;
}
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
cout.width(5);
cout << A[i][j];
} printf ("\n"); }
}
int main() {
int i, v1, v2; Create();
for (v1 = 1; v1 <= n; v1++)
v[v1] = 0;
DFS (1);
for (i = 1; i < 2*n-1; i += 2)
printf ("%d - %d \n", T[i], T[i+1]);
return 0;
}
Code Maple DFS
with(GraphTheory):
G := Graph( [1, 2, 3, 4, 5, 6, 7, 8, 9]);
AddEdge( G, { {1, 2}, {1, 3}, {2, 4}, {2, 5}, {2, 6}, {3, 7}, {3, 8}, {3, 9} });
DrawGraph(G);
DFS := proc(k::integer)
local i; global Kt, A, n, E;
Kt := Kt union {k};
for i from 1 to n do
if A(k, i) != 0 and i Kt then
E := AddEdge(E, {k, i} ); DFS(i);
end if;
end do;
end proc:
main := proc(G::Graph, k)
global n, A, E, Kt;
30

n := NumberOfVertices(G); A := AdjacencyMatrix(G);
E := Graph(n); Kt := { };
if not IsConnected(G) then
return ("Do thi nay ko lien thong");
end if;
DFS(k);
return E;
end proc:
with(GraphTheory):
with(RandomGraphs):
G := RandomGraph( 8, 10, connected, weights = 1..10);
T := main(G, 2);
HighlightEdges(G, T, red);
DrawGraph(G);
To 1 mng c 10 phn t = 0 trong Maple:
V := [ seq( 0, i = 1..10) ];
V := array(1..n)
for i from 1 to n do
V[i] := 0;
end do;

Depth First Search Algorithm


- Given graph G = (X, E), X is the set of vertices, E is the set of edges.
- Step 1: Sorting the vertices by order: x1, x2, x3... Choose arbitrary vertex x = x1,
A = X {x1} (remove x1 out of set of vertices). Initialize set of edges T = .
- Step 2: If N(x) (set of vertices near x) intersect with A = , so going to Step 4.
If N(x) intersect with A , so going to Step 3.
- Step 3: Choose min i so that xi in N(x) intersect with A,
and choosing e = {x, xi}. T = T + e, A = A xi, x = xi. Return Step 2.
- Step 4: If x = x1 then stopping. T is the Tree.
If x x1, then search predecessor (phn t trc) x: x = pre(x). Return Step 2.

31

1
2
3
4
5
6
7
8
9

1
0

2
1
0

3
1
0
0

4
0
1
0
0

5
0
1
0
0
0

6
0
1
0
0
0
0

7
0
0
1
0
0
0
0

8
0
0
1
0
0
0
0
0

9
0
0
1
0
0
0
0
0
0

int x1[] = { 1, 1, 0, 0, 0, 0, 0, 0,/ 0, 1, 1, 1, 0, 0, 0,/ 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,/ 0, 0, 0,


0,/ 0, 0, 0,/ 0, 0,/ 0};
int x1[] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0};
- Step 1: Khi to mng v[9] = {0}. Chn x1 l phn t bt u, v[1] = 1, nh
du phn t x1. B x1 khi A: A = { x2, x3, x4, x5, x6, x7, x8, x9}
- Step 2: If (v[2] == 0 && A[1][2] != 0), chn x2 l phn t nh nht k vi x1, x
= x2. Thm vo T cnh {x1, x2}. v[2] = 1, b x2 khi A: A = { x3, x4, x5, x6, x7, x8,
x9}
- Step 2: If (v[4] == 0 && A[2][4] != 0), chn x4 l phn t nh nht k vi x2, x
= x4. Thm vo T cnh {x2, x4}. v[4] = 1, b x4 khi A: A = { x3, x5, x6, x7, x8,
x9}
- Step 3: V giao cc nh k ca x4 vi A = nn d ngc pre(x4) = x2.
- Step 2: If (v[5] == 0 && A[2][5] != 0), chn x5 l phn t k tip k vi x2, x =
x5. Thm vo T cnh {x2, x5}. v[5] = 1, b x5 khi A: A = { x3, x6, x7, x8, x9 }
- Step 3: V giao cc nh k ca x5 vi A = nn d ngc pre(x5) = x2.
- Step 2: If (v[6] == 0 && A[2][6] != 0), chn x6 l phn t k tip k vi x2, x =
x6. Thm vo T cnh {x2, x6}. v[6] = 1, b x6 khi A: A = { x3, x7, x8, x9 }
- Step 3: V giao cc nh k ca x6 vi A = nn d ngc pre(x6) = x2.
V giao cc nh k ca x2 vi A = nn d ngc pre(x2) = x1.

32

- Step 2: If (v[3] == 0 && A[1][3] != 0), chn x3 l phn t k tip k vi x1, x =


x3. Thm vo T cnh {x1, x3}. v[3] = 1, b x3 khi A: A = { x7, x8, x9 }
T = { {x1, x2}, {x2, x4}, {x2, x5}, {x2, x6}, {x1, x3}, {x3, x7}, {x3, x8}, {x3,
x9} }
Breadth First Search Algorithm
- Given graph G = (X, E), X is the set of vertices, E is the set of edges.
- Step 1: Sorting the vertices by order: x1, x2, x3... Choose arbitrary vertex x = x1,
A = {x1}, B = X {x1} (remove x1 out of set of vertices). Initialize set of edges T =
. N(x) is the set of vertices near x.
- Step 2: If B = then stopping. T is the tree.
If B then going to Step 3 where S = .
- Step 3: Put x = minA. If N(x) intersect with B = then going Step 4.
If N(x) intersect with B = { y1,..., yk } then choosing the edges e = xyj and
T = T + e1 +... ek, B = B { y1,..., yk }.
S = S + { y1,..., yk }
- Step 4: A = A {x}. If A is different Null, then returning Step 2.
If A is Null, then returning Step 3 with A = S.

- Step 1: Khi to mng v1[9] = {0}. Chn x1 l phn t bt u, v1[1] = 1, v1[]


l mng nh du phn t x1 ca B. B x1 khi B: B = { x2, x3, x4, x5, x6, x7, x8,
x9 }, v[1] = 1, A = {x1}. v2[9] = {0}, v2[] l mng nh du phn t ca S.
T = , S = .
- Step 2: If B then going to Step 3 with S = .
B :
for (i = 0; i < n; i++)
if (v1[i] == 0)
S = :
for (i = 0; i < n; i++)
v2[i] = 0;
- Step 3: Put x = minA = x1, N(x) intersect with B = {x2, x3}.
33

T = T + {x1, x2} + {x1, x3}; v[2] = v[3] = 1;


B = B {x2, x3} = { x4, x5, x6, x7, x8, x9 }; S = S + {x2, x3} = {x2, x3}.
- Step 4: A = A {x1} = Null; returning Step 2 with A = S.
- Step 2: If B then going to Step 3 with S = .
- Step 3: Put x = minA = x2, N(x) intersect with B = { x4, x5, x6 }.
T = T + {x2, x4} + {x2, x5} + {x2, x6}; v[4] = v[5] = v[6] = 1;
B = B { x4, x5, x6 } = { x7, x8, x9 }; S = { x4, x5, x6 }.
- Step 4: A = A {x2} = {x3}; returning Step 3.
- Step 3: Put x = minA = x3, N(x) intersect with B = { x7, x8, x9 }.
T = T + {x3, x7} + {x3, x8} + {x3, x9}; v[7] = v[8] = v[9] = 1;
B = B { x7, x8, x9 } = Null. S = { x7, x8, x9 }.
- Step 4: A = A {x3} = Null; returning Step 2.
- Step 2: If B = Null then stopping algorithm. T is the Tree.
T = { {x1, x2}, {x1, x3}, {x2, x4}, {x2, x5}, {x2, x6}, {x3, x7}, {x3, x8}, {x3, x9} }
BFS Code Maple
with(GraphTheory):
G := Graph( [1, 2, 3, 4, 5, 6, 7, 8, 9]);
AddEdge( G, { {1, 2}, {1, 3}, {2, 4}, {2, 5}, {2, 6}, {3, 7}, {3, 8}, {3, 9} });
DrawGraph(G);
BFS := proc( G::Graph, x1)
local A, B, C, S, T, x, y, n; A := {x1};
n := NumberOfVertices(G); T := Graph(n);
B := { op(Vertices(G)) }; B := B minus {x1}; S := { };
if not IsConnected(G) then
return ("Do thi nay ko lien thong");
end if;
while not (B = { }) do
x := A[1];
C := { op(Neighbors(G, x) ) } intersect B; B := B minus C;
for y in C do
T := AddEdge( T, {x, y}); end do;
S := S union C; A := A minus {x};
if A = { } then A := A union S; end if;
S := { }; C := { };
end do;
return T;
end proc:
with(GraphTheory):
with(RandomGraphs):
G := RandomGraph( 8, 10, connected, weights = 1..10);
T := BFS(G, 2);
34

HighlightEdges(G, T, red);
DrawGraph(G);
BFS Code C++
#include <iostream.h>
class Queue {
private:
int data;
Queue *Next;
public:
void Enque (int data);
int Deque();
} *Head, *Tail;
void Queue :: Enque (int data) {
Queue *temp; temp = new Queue;
temp->data = data; temp->Next=NULL;
if (Head == NULL)
Head = temp;
else
Tail->Next = temp;
Tail = temp;
}
int Queue :: Deque() {
Queue* temp; temp = Head;
Head = Head->Next;
return temp->data;
}
int visit[100];
int bfs_span_tree[100][100];
class Graph {
private:
int a;
Graph *Next;
public:
void BFS();
Graph* Create (Graph* Head, int *x, int n);
void Ftraverse (Graph *Head);
};
Graph* Graph :: Create (Graph *Head, int *x, int n) {
int a, i, k; k = 0; Graph *last; Head = last = NULL;
Graph *temp;
for (i = 0; i < n; i++) {
temp = new Graph; temp->a = x[i];
temp->Next = NULL;
35

if (Head == NULL)
Head = temp;
else
last->Next = temp;
last = temp;
}
return Head;
}
void Graph :: Ftraverse (Graph *h) {
while (h != NULL) {
cout << h->a << "->";
h = h->Next; }
cout << "NULL \n";
}
void Graph :: BFS() {
cout << "This program is to implement BFS for an unweighted graph \n";
Graph *ptr[100]; int n, i; n = 2;
int x1[9] = { 1, 2, 4, 6, 7, 3, 5, 1, 6 };
int x2[9] = { 4, 7, 3, 5, 1, 2, 5, 7, 4};
ptr[1] = Create (ptr[1], x1, 9); ptr[2] = Create (ptr[2], x2, 9);
cout << "\n The Entered Graph is ::\n";
for (i = 1; i <= n; i++) {
cout << "< " << i << " > ::";
Ftraverse (ptr[i]);
}
int x;
cout << "\n Enter the start node " << n << ">:"; cin >> x;
cout << "\n The Breadth first search traversal is: \n";
Queue object;
// Mark all the nodes as not viseted
for (i = 1; i <= n; i++)
visit[i] = 0;
for (i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
bfs_span_tree[i][j] = 0;
// Enque the start node
object.Enque (x);
int p;
while (Head != NULL && Tail != NULL) {
// Deque a node
p = object.Deque();
int x = p;
// If p is not visited yet.
while (ptr[p] != NULL) {
if (visit [ptr [p]->a] != 1) {
cout << "node " << ptr[p]->a << " is visited \n";
36

// Mark the node as visited.


visit [ptr [p]->a] = 1;
bfs_span_tree [ptr [p]->a] [x] = 1;
}
// Enque all its adjacent nodes.
object.Enque (ptr[p]->a);
ptr[p] = ptr[p]->Next;
} }
cout << "\n The required bfs spanning tree is ::\n";
for (i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
cout << bfs_span_tree[i][j] << ' ';
cout << "\n";
}
cout << "\n";
}
int main() {
Graph obj;
obj.BFS();
return 0;
}

Dijkstra Algorithm
- Cho th G = (X, E) vi cc cnh c trng s ko m.
- D liu nhp cho thut ton l ma trn trng s L v 2 nh x, y cho trc. (vi
quy c L(x, y) = 999 nu ko c cnh ni t nh x n nh y).
- D liu xut l ng i ngn nht t x n y.
Step 1: Assign (gn) T = X, the set of vertices (cc nh) of graph.
Initial (khi ng): length[x] = 0; with every k in X \{x}, length[k] = 999.
last[k] = 0; mark[k] = 0.
- length[k] is the length of path from vertex x to vertex k. last[] is the array to save
the path element. mark[] is the array to mark the elements whether is visited or not.
Step 2: If y not in T, Stop.
Choose vertex v in T so that length[v] is min and remove v out of T. mark[v] = 1.
Step 3:
With every vertex k in T, and there exist an edge from v to k.
If length[k] > length[v] + L(v, k) // weight of edge from v to k.
length[k] = length[v] + L(v, k)
last[k] = v.
Continuos step 2.
Code Dijkstra Algorithm

37

#include <iostream.h>
#include <stdio.h>
class Dijkstra {
private:
int graph[15][15];
int last[15], mark[15], length[15];
int source;
int n; // num_of_vertices
public:
int Minimum();
int Read();
void Initialize (int source);
void Printpath (int i);
void Algorithm (int source);
void Output();
};
int Dijkstra::Read() {
n = 5; int i, j, k = 0;
int x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19};
cout << "enter the adjacent matrix: \n";
for (i = 1; i <= n; i++)
for (j = i+1; j <= n; j++) {
graph[j][i] = graph[i][j] = x1[k]; k++;
}
for (i = 1; i <= n; i++)
graph[i][i] = 0;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++)
printf ("%d ", graph[i][j]);
printf ("\n");
}
cout << "\n enter the source vertex \n";
cin >> source;
return source;
}
void Dijkstra::Initialize (int source) {
int i;
for (i = 1; i <= n; i++) {
mark[i] = 0;
length[i] = 999;
last[i] = 0;
}
length [source] = 0;
}
void Dijkstra::Algorithm (int source) {
38

Initialize (source); int count = 0, i, u;


while (count < n) {
u = Minimum();
printf ("u = Minimum() = %d \n", u);
count++; mark[u] = 1;
printf ("mark[%d] = 1 \n", u);
for (i = 1; i <= n; i++)
if (graph[u][i] > 0) {
if (mark[i] != 1) {
printf ("if (mark[%d] != 1) \n", i);
if (length[i] > length[u] + graph[u][i]) {
printf ("if (length[%d] > length[%d] + graph[%d][%d]) \n", i, u, u, i);
printf ("length[%d] = %d, length[%d] = %d \n", i, length[i], u,
length[u]);
printf ("graph[%d][%d] = %d \n", u, i, graph[u][i]);
length[i] = length[u] + graph[u][i];
last[i] = u;
printf ("length[%d] = length[%d] + graph[%d][%d] = %d \n", i, u, u, i,
length[i]);
printf ("last[%d] = %d \n", i, u);
}
} } /* End if (graph[u][i] > 0) */
} }
void Dijkstra::Printpath (int i) {
cout << endl;
if (i == source)
cout << source;
else if (last[i] == 0)
cout << "no path from " << source << " to " << i;
else {
Printpath (last[i]);
cout << "..." <<i; }
}
void Dijkstra::Output() {
int i;
for (i = 1; i <= n; i++) {
Printpath(i);
if (length[i] != 999)
cout << "->(" << length[i] << ") \n";
} cout << endl;
}
int Dijkstra::Minimum() {
int min = 999; int i, t;
for (i = 1; i <= n; i++) {
if (mark[i] != 1) {
39

if (min >= length[i]) {


min = length[i];
t = i;
} }
} return t;
}
int main() {
int source; Dijkstra s; source = s.Read();
s.Algorithm (source); s.Printpath(4);
return 0;
}
Code Maple Dijsktra
with(GraphTheory): with(RandomGraphs):
with(LinearAlgebra):
Dijsktra := proc()
global m, n, DoDai, Browse, Kt;
local i, v, min;
while Kt != do
min := 999; v := 0;
for i in Kt do
if min >= DoDai[i] then min := DoDai[i]; v := i; end if;
end do;
Kt := Kt minus {v};
for i in Kt do
if A[i, v] > 0 and DoDai[i] > DoDai[v] + A[i, v] then
DoDai[i] := DoDai[v] + A[i, v];
Browse[i] := v;
end if;
end do;
end do;
end proc:
ve := proc(x0)
local i, E; E := Digraph(n);
for i from 1 to n do
if Truoc[i] != i then E := AddArc(E, { [Browse[i], i] }); end if;
end do;
print(E);
HighlightEdges(G, E, red); HightlightVertex(G, x0, red);
print( DrawGraph(E) );
end proc:

40

khoitao := proc(G::Graph, x0)


global m, n, DoDai, Browse, Kt, A;
local i, j;
A := WeightMatrix(G); n := NumberOfVertices(G);
Kt := { }; Browse := array(1..n); DoDai := array(1..n);
if not IsConnected(G) then
return ("Do thi nay ko lien thong");
end if;
for i from 1 to n do
Kt := Kt union {i};
Browse[i] := i; DoDai[i] := 999;
end do;
for i from 1 to n do
for j from 1 to n do
if A[i, j] = 0 then A[i, j] := 999; end if;
end do; end do;
DoDai[x0] := 0;
HighlightVertex(G, x0, red);
end proc:
with(GraphTheory):
with(RandomGraphs):
G := RandomGraph( 8, 10, connected, weights = 1..10);
khoitao(G, 1)
Dijsktra();
ve(1);
Dijkstra Algorithm run by hand
> with(GraphTheory):
G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4},
6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );
DrawGraph(G);

41

WeightMatrix(G);
1
2
3
4
5

1
0
3
24
35
16

2
3
0
5
6
17

3
24
5
0
7
38

4
35
6
7
0
19

5
16
17
38
19
0

int x1[] = { 0, 3, 24, 35, 16, 3, 0, 5, 6, 17, 24, 5, 0, 7, 38, 35, 6, 7, 0, 19, 16, 17, 38,
19, 0 };
int x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19};
DijkstrasAlgorithm( G, 1, 4 );
[ [1, 2, 3, 4], 15]
Tm ng i ngn nht t nh 1 n nh 4;
Step 1: Assign T = X\{x}, the set of vertices of graph.
Initial (khi ng): length[1] = 0; with every k in X \{x}, length[k] = 999.
last[k] = 0; mark[k] = 0.
- length[k] is the length of path from vertex x to vertex k. last[] is the array to save
the path element. mark[] is the array to mark the elements whether is visited or not.
Step 2: If y not in T, Stop.
Choose vertex v in T so that length[v] is min and remove v out of T. mark[v] = 1.
Step 3:
With every vertex k in T, and there exist an edge from v to k.
If length[k] > length[v] + L(v, k) // weight of edge from v to k.
length[k] = length[v] + L(v, k)
last[k] = v.
Continue step 2.
42

Step 2: Choose v = 1, length[1] = 0 is min; mark[1] = 1; T = { 2, 3, 4, 5 };


Step 3: The vertices k in T that there exist and edge from 1 to k: 2, 3, 4, 5.
for (i = 1; i <= 5; i++)
If (mark[2] != 1) {
If (length[2] > length[v] + L(v, k) ) {
// length[2] = 999; length[v] = length[1] = 0; L(v, k) = L(1, 2) = 3;
length[2] = length[1] + L(1, 2) = 3;
last[2] = 1; }
}
if (mark[3] != 1)
if (length[3] > length[1] + L(1, 3) )
// length[3] = 999; length[1] = 0; L(1, 3) = 24;
length[3] = length[1] + L(1, 3) = 24;
last[3] = 1;
}
if (mark[4] != 1) {
if (length[4] > length[1] + L(1, 4) ) {
// length[4] = 999; length[1] = 0; L(1, 4) = 35;
length[4] = length[1] + L(1, 4) = 35;
last[4] = 1; }
}
if (mark[5] != 1) {
if (length[5] > length[1] + L(1, 5) ) {
// length[5] = 999; length[1] = 0; L(1, 5) = 16;
length[5] = length[1] + L(1, 5) = 16;
last[5] = 1; }
}
Step 2: Choose v = 2, length[2] = 3 is min; mark[2] = 1; T = { 3, 4, 5 };
Step 3: The vertices k in T that there exist and edge from 2 to k: 3, 4, 5.
for (i = 1; i <= 5; i++)
If (mark[3] != 1)
If (length[3] > length[2] + L(2, 3) )
// length[3] = 24; length[2] = 3; L(2, 3) = 5;
length[3] = length[1] + L(2, 3) = 8;
last[3] = 2;
}
If (mark[4] != 1) {
If (length[4] > length[2] + L(2, 4) ) {
// length[4] = 35; length[2] = 3; L(2, 4) = 6;
length[4] = length[2] + L(2, 4) = 9;
last[4] = 2; }
}
If (mark[5] != 1) {
43

If (length[5] < length[2] + L(2, 5) ) {


// length[5] = 16; length[2] = 3; L(2, 5) = 17;
Stop; }
}
Step 2: Choose v = 3, length[3] = 8 is min; mark[3] = 1; T = { 4, 5 };
Step 3: The vertices k in T that there exist and edge from 3 to k: 4, 5.
for (i = 1; i <= 5; i++)
If (mark[4] != 1) {
If (length[4] < length[3] + L(3, 4) )
// length[4] = 9; length[3] = 8; L(3, 4) = 7;
Stop; }
}
If (mark[5] != 1) {
If (length[5] < length[3] + L(3, 5) ) {
// length[5] = 16; length[3] = 8; L(3, 5) = 38;
Stop; }
}
Step 2: Choose v = 4, length[4] = 9 is min; mark[4] = 1; T = { 5 };
Step 3: The vertices k in T that there exist and edge from 4 to k: 5.
for (i = 1; i <= 5; i++)
If (mark[5] != 1) {
If (length[5] < length[4] + L(4, 5) ) {
// length[5] = 16; length[4] = 9; L(4, 5) = 19;
Stop; }
}
Step 2: If v = 4 == y is not in T. Stop;
The path:
void Dijkstra::Printpath (int i) {
cout << endl;
if (i == source)
cout << source;
else if (last[i] == 0)
cout << "no path from " << source << " to " << i;
else {
Printpath (last[i]);
cout << "..." << i; }
}
Printpath(4);
if (last[4] = 2 != 0) Printpath(2);
if (last[2] = 1 != 0) Printpath(1);
if (i = 1 == source) cout << "..." << i;
44

1 2 4.
Bellman-Ford Algorithm
- Step 1: Initialize: P[0][x] = 0; P[0][i] = 9999, with every i x, k = 1.
- Step 2: With every vertex i in X, we calculate:
P[k][i] = min ( { P[k-1][i] }, { P[k-1][j] + L[i][j] ). There exists path from i to j.
L[i][j] is the weight matrix.
- Step 3: If row k and row k-1 of matrix P are equal then P[k][i] is the length of
shortest path from x to i.
If row k and row k-1 of matrix P are different
If k < n then increasing k = k + 1 and returning Step 2.
If k == n then stopping cause graph have negative path.

#include
#include
#include
#define

<iostream.h>
<stdio.h>
<stdlib.h>
MAX 20

class bell_ford {
private:
int n; int graph[MAX][MAX]; int start;
int distance[MAX]; int pre[MAX];
public:
void read_graph();
void initialize();
void update();
void check();
void algorithm();
};
void bell_ford::read_graph() {
int i, j, k; n = 5; k = 0;
int x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 };
for (i = 1; i <= n; i++)
for (j = i+1; j <= n; j++) {
graph[j][i] = graph[i][j] = x1[k]; k++; }
for (i = 1; i <= n; i++)
graph[i][i] = 0;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
printf ("%d ", graph[i][j]); }
printf ("\n"); }
cout << "Enter the start vertex ::";
45

cin >> start;


}
void bell_ford::initialize() {
int i;
for (i = 1; i <= 5; i++) {
distance[i] = 9999;
pre[i] = 0;
} distance[start] = 0;
}
void bell_ford::update() {
int i, u, v;
printf ("update \n");
for (u = 1; u <= n; u++)
for (v = 1; v <= n; v++)
if (graph[u][v] != 0) {
if (distance[v] > distance[u] + graph[u][v]) {
printf ("\n if (distance[%d] > distance[%d] + graph[%d][%d] ) \n", v, u, u,
v);
printf ("distance[%d] = %d, distance[%d] = %d \n", v, distance[v], u,
distance[u]);
printf ("graph[%d][%d] = %d \n", u, v, graph[u][v]);
distance[v] = distance[u] + graph[u][v];
printf ("distance[%d] = distance[%d] + graph[%d][%d] = %d \n", v, u, u, v,
distance[v]);
pre[v] = u;
printf ("pre[%d] = %d \n", v, u);
}
else {
printf ("\n if (distance[%d] < distance[%d] + graph[%d][%d] ) \n", v, u, u,
v);
printf ("distance[%d] = %d, distance[%d] = %d \n", v, distance[v], u,
distance[u]);
printf ("graph[%d][%d] = %d \n", u, v, graph[u][v]);
printf ("continue \n");
}
}
}
void bell_ford::check () {
int i, j, u, v;
printf ("Check Function \n");
for (u = 1; u <= n; u++)
for (v = 1; v <= n; v++) {
if (graph[u][v] != 0) {
if (distance[v] > distance[u] + graph[u][v]) {
cout << "does not exist's ";
46

return;
} } }
cout << "\n\n There is no negative weight cycle and \n";
cout << "The final paths and the distances are \n";
for (i = 1; i <= n; i++) {
cout << "path for node " << i << " is ::\n";
int arr[MAX], k = 1; j = i;
while (pre[j] != 0) {
printf ("while pre[%d] != 0 \n", j);
arr[k] = pre[j]; k++;
printf ("arr[%d] = pre[%d] = %d \n", k-1, j, arr[k-1]);
printf ("j = pre[%d] = %d, k = %d \n", j, pre[j], k);
j = pre[j];
}
for (k = k - 1; k > 0; k--)
printf ("arr[%d] = %d -> ", k, arr[k]);
cout << i << endl;
cout << "distance is " << distance[i] << endl << endl;
}
}
void bell_ford::algorithm() {
read_graph(); initialize();
update(); check();
}
int main() {
bell_ford obj;
obj.algorithm();
}
BellmanFord Code 2.
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
struct Edge{
int source;
int dest;
int weight;
};
void BellmanFord (Edge edges[], int edgecount, int nodecount, int source) {
int *d = new int [nodecount + 1];
int i, j, k1, k2, k3, d1;
for (i = 0; i <= nodecount; i++)
d[i] = 9999;
47

d[source] = 0;
for (i = 0; i < edgecount; i++) {
k1 = edges[i].source; k2 = d[edges[i].source];
k3 = edges[i].dest;
if (d[edges[i].source] != 9999) {
printf ("\n if (d[%d] = %d != 9999) \n", k1, k2);
d1 = d[edges[i].source] + edges[i].weight;
printf ("d1 = d[%d] + edges[%d].weight = %d \n", k1, i, d1);
printf ("edges[%d].source = %d \n", i, k1);
printf ("edges[%d].dest = %d \n", i, k3);
printf ("edges[%d].weight = %d \n", i, edges[i].weight);
if (d1 < d[edges[i].dest]) {
printf ("if (d1 = %d < d[%d] = %d) \n", d1, k3, d[k3]);
d[edges[i].dest] = d1;
printf ("d[%d] = %d \n", k3, d1);
}
else {
printf ("if (d1 = %d > d[%d] = %d) \n", d1, k3, d[k3]);
printf ("continue \n");
}
}
}
for (i = 0; i < edgecount; i++)
if (d[edges[i].dest] > d[edges[i].source] + edges[i].weight) {
printf ("Negative edge weight cycles detected!");
free(d);
return;
}
for (i = 1; i <= nodecount; i++) {
printf ("The shortest distance between nodes %d and %d is %d \n",
source, i, d[i]);
}
free(d);
return;
}
int main() {
Edge edges[10] = { {1, 2, 3}, {1, 3, 24}, {1, 4, 35}, {1, 5, 16},
{2, 3, 5}, {2, 4, 6}, {2, 5, 17}, {3, 4, 7}, {3, 5, 38}, {4, 5, 19} };
BellmanFord (edges, 10, 5, 1);
return 0;
}
Bellman-Ford run by hand
> with(GraphTheory):
48

G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4},
6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );
DrawGraph(G);

BellmanFordAlgorithm( G, 1, 4);
Edge edges[10] = { {1, 2, 3}, {1, 3, 24}, {1, 4, 35}, {1, 5, 16}, {2, 3, 5},
{2, 4, 6}, {2, 5, 17}, {3, 4, 7}, {3, 5, 38}, {4, 5, 19} };
- Step 1: Initialize distance[i] = 9999 with every i 1.
distance [1] = 0; pre[i] = 0 with every i in X (set of vertices).
- Step 2:
for (u = 1; u <= n; u++)
for (v = 1; v <= n; v++)
if (graph[1][2] == 3 != 0)
if (distance[2] > distance[1] + graph[1][2])
distance[2] = 9999; distance[1] = 0; graph[1][2] = 3;
distance[2] = distance[1] + graph[1][2] = 3.
pre[2] = 1;
if (graph[1][3] == 24 != 0)
if (distance[3] > distance[1] + graph[1][3])
distance[3] = 9999; distance[1] = 0; graph[1][3] = 24;
distance[3] = distance[1] + graph[1][3] = 24.
pre[3] = 1;
if (graph[1][4] == 35 != 0)
if (distance[4] > distance[1] + graph[1][4])
distance[4] = 9999; distance[1] = 0; graph[1][4] = 35;
distance[4] = distance[1] + graph[1][4] = 35.
pre[4] = 1;

49

if (graph[1][5] == 16 != 0)
if (distance[5] > distance[1] + graph[1][5])
distance[5] = 9999; distance[1] = 0; graph[1][5] = 16;
distance[5] = distance[1] + graph[1][5] = 16.
pre[5] = 1;
if (graph[2][1] == 3 != 0)
if (distance[1] < distance[2] + graph[2][1])
distance[1] = 0; distance[2] = 3; graph[2][1] = 3;
continue;
if (graph[2][3] == 5 != 0)
if (distance[3] > distance[2] + graph[2][3])
distance[3] = 24; distance[2] = 3; graph[2][3] = 5;
distance[3] = distance[2] + graph[2][3] = 8.
pre[3] = 2;
if (graph[2][4] == 6 != 0)
if (distance[4] > distance[2] + graph[2][4])
distance[4] = 35; distance[2] = 3; graph[2][4] = 6;
distance[4] = distance[2] + graph[2][4] = 9.
pre[4] = 2;
if (graph[2][5] == 17 != 0)
if (distance[5] < distance[2] + graph[2][5])
distance[5] = 16; distance[2] = 3; graph[2][5] = 17;
continue;
path for node 3 is:
while (pre[j] != 0)
arr[1] = pre[j] = pre[3] = 2;
j = pre[3] = 2;
arr[1] = pre[2] = 1;
1 2 3; distance = 8.

Floyd Code
#include <stdio.h>
#include <stdlib.h>
#include <string>
/* Floyd's All pairs shortest path algorithm (O (n^3) ).
input is adjacency matrix output is matrix of shortest paths.
C is the adjacency matrix.
n is the order of the square matrix.
50

A is the all pairs shortest paths matrix.


we assume that A is allocated by the caller. */
int Floyd (int *A, int n) {
int i, j, k;
// for each route via k from i to j pick any better routes and
// replace A[i][j] path with sum of paths i-k and j-k
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if ( A[i*n + k] + A[k*n + j] < A[i*n + j]) {
// A[i][j] = A[i][k] + A[k][j];
A[i*n + j] = A[i*n + k]+ A[k*n + j];
}
return 0;
}
void FloydTest() {
int n = 5, i, j, k; k = 0;
int *C = new int[n*n];
int x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 };
for (i = 0; i < n; i++)
for (j = i+1; j < n; j++) {
C[j*n + i] = C[i*n + j] = x1[k]; k++; }
for (i = 0; i < n; i++)
C[i*n + i] = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf ("%d ", C[i*n + j]); }
printf ("\n"); }
int *A = new int[n*n];
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if ( C[i*n + j] == 0) {
A[i*n + j] = 9999; // Does this look like infinity?
}
else {
A[i*n + j] = C[i*n + j];
}
// set the diagonals to zero
for (i = 0; i < n; i++) {
A[i*n + i] = 0; }
Floyd (A, n);
for (i = 0; i < n; i++)
for (j = i+1; j < n; j++) {
printf ("path from %d to %d is %d\n", i+1, j+1, A[i*n+j]);
51

} printf("\n");
delete []A; delete []C;
}
int main() {
FloydTest();
}
Code Maple Floyd 1
with(GraphTheory):
G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4},
6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );
DrawGraph(G);
Floyd := proc(G::Graph)
local i, j, k, n, A, B;
A := WeightMatrix(G); n := NumberOfVertices(G);
B := Matrix(n);
if not IsConnected(G) then
return ("Do thi nay ko lien thong");
end if;
for i from 1 to n do
for j from 1 to n do
if A[i, j] > 0 then
for k from 1 to n do
if A[i, k] > 0 then
if A[j, k] < A[j, i] + A[i, k] then
B[j, k] := A[j, i] + A[i, k]; end if;
end if;
end do;
end if;
end do; end do;
return B;
end proc:
A := Floyd(G);
Code Maple Floyd 2
with(GraphTheory): with(RandomGraphs):
Floyd := proc(G::Graph)
local M, M1, M2, i, j, a, n, k;
M := WeightMatrix(G); n := NumberOfVertices(G);
k := 1; M1 := Matrix( M, datatype = anything); M2 := Matrix(n);
for i from 1 to n do
for j from 1 to n do
52

if [i, j] Edges(G) and i != j then M1[i, j] :=


else M2[i, j] := j; end if;
end do; end do;
while (k n) do
for i from 1 to n do
for j from 1 to n do
a := M1[i, k] + M1[k, j];
if (a < 0) and (i = j) then
error "Co mach am"; end if;
if (M1[i, j] > a) then
M1[i, j] := a; M2[i, j] := M2[i, k]; end if;
end do; end do;
k := k + 1;
end do;
print( M1, M2 );
end proc:
G1 := RandomDigraph( 5, 10, weights = -10..10 );
DrawGraph(G1); Floyd(G1);
Chu trnh Euler
Euler Cycle
Fleury Algorithm for finding an Euler Cycle
- Starting from arbitrary vertex and using two following rules:
- Rule 1: Remove the edges were browsed and isolated vertices (im c lp).
- Rule 2: At every vertices, we only use one path.
> with(GraphTheory):
with(SpecialGraphs):
G := CompleteGraph(5);
DrawGraph(G);

53

IsEulerian( G, 'T');
true;
T = Trail( 1, 2, 3, 1, 4, 2, 5, 3, 4, 5, 1);
- Starting from vertex 1; Trong s cc nh k vi nh 1 th nh 2 l nh nh
nht v cnh {1, 2} cha qua, thm cnh {1, 2} vo T.
- Trong s cc nh k vi nh 2 th nh 3 l nh nh nht v cnh {2, 3} cha
qua, thm cnh {2, 3} vo T.
- Trong s cc nh k vi nh 3 th nh 1 l nh nh nht v cnh {3, 1} cha
qua, thm cnh {3, 1} vo T.
- Trong s cc nh k vi nh 1 th nh 4 l nh nh nht v cnh {1, 4} cha
qua, thm cnh {1, 4} vo T.
- Trong s cc nh k vi nh 4 th nh 2 l nh nh nht v cnh {4, 2} cha
qua, thm cnh {4, 2} vo T.
DeleteEdge(G, { {1, 2}, {2, 3}, {3, 1}, {1, 4}, {4, 2} } );
DrawGraph(G);

Euler Cycle Maple Code 1


with(GraphTheory):
with(RandomGraphs):
Euler := proc(G::Graph, x0)
global n, Result, A, B, t1; local i, j, t, x, Kt;
x:= x0; Kt := { };
Kt := { op( Neighbors(G, x) ) };
for i in Kt do
if B[x, i] != 0 then
Result[t1] := i; t1 := t1 + 1;
B[x, i] := 0; B[i, x] := 0; Euler(G, i);
end if;
end do;
end proc:

54

main := proc(G::Graph, x0)


global n, A, B, t1, Result; local i, t;
n := NumberOfVertices(G); t := 0;
A := AdjacencyMatrix(G); Result := array(1..n.n);
B := A; t1 := 2;
print( DrawGraph(G) );
if not IsConnected(G) then
return ("Do thi nay ko lien thong");
end if;
for i in Vertices(G) do
if (Degree(G, i) mod 2 = 1) then
t := t + 1; end if;
end do;
if (t != 0 and (t != 2 or (Degree(G, x0) mod 2) = 0 ) ) then
error ("Dont have any Euler");
end if;
for i from 1 to n.n do
Result[i] := 0;
end do;
Euler(G, x0); Result[1] := x0;
print( Result );
end proc:
G1 := RandomGraph(5, 8, Connected); DrawGraph(G1);
main(G1, 4);
Euler Cycle Maple Code 2
with(GraphTheory): with(RandomGraphs): with(LinearAlgebra):
Euler := proc(G::Graph, x0)
local M, n, t, i, Road, Stack, x, X, k;
# M: Ma trn k, n: s nh ca th G, Road: biu din ng i Euler.
# Stack: ngn xp, x: phn t cui ca Road, X: tp hp.
# k: s phn t ca Stack.
if (IsConnected(G) = false or IsDirected(G) = true) then
error ("Data Error"); end if;
M := AdjacencyMatrix(G); t := 0;
n := nops( Vertices(G) ); print(n);
for i in Vertices(G) do
if (Degree(G, i) mod 2 = 1) then
t := t + 1; end if;
end do;
if (t != 0 and (t != 2 or (Degree(G, x0) mod 2) = 0 ) ) then
error ("Dont have any Euler");
end if;
55

Stack := Matrix([x0]); X := { };
Road := Matrix([ ]);
while Equal( Stack, Matrix([ ]) ) = false do
k := ArrayNumElems(Stack);
x := Stack( 1, k );
i := 1;
while (i < n + 1) and (M(x, i) = 0 or (M(x, i) = 1 and i X) ) do
i := i + 1;
if (i = n + 1) then break; end if;
end do;
if (i < n + 1) then
Stack := <Stack|i>;
M[i, x] := 0;
else if Equal( M, AdjacencyMatrix(G) ) then
M[ Stack( k ), Stack( k - 1 ) ] := 1;
end if;
Road := <Stack( 1, k ) | Road>;
X := X union { Stack( k ) };
Stack := DeleteColumn( Stack, [k] );
end if;
end do;
print(Road);
end proc:
G1 := RandomGraph(5, 8, Connected); DrawGraph(G1);
Euler(G1, 4);
Stack:
with(LinearAlgebra):
Stack := Matrix([3]);
Stack := <Stack | 5>; # Thm phn t 5 vo Stack;
Stack := <Stack | 7>;
k := ArrayNumElems(Stack): # k l s phn t ca Stack;
i := Stack(1, k): # i l phn t cui ca Stack;
j := Stack(1, 1): # i l phn t u ca Stack;
print(`k = `, k, `i = `, i, `j = `, j);
Stack := DeleteColumn( Stack, [k] ); # Delete phn t cui ca Stack;
s := stack[new](1, 2, 3): # Khi to Stack.
stack[push]( 7, s ): # Thm phn t 7 vo Stack;
print(s);
k := stack[depth](s); # k l s phn t ca Stack;
56

i := stack[pop](s); # i l phn t cui ca Stack;


with(GraphTheory):
with(RandomGraphs):
G := CompleteGraph(7);
DrawGraph(G);

IsEulerian(G, T);
T
Trail( 1, 2, 3,/ 1, 4, 2, 5,/ 1, 6, 2, 7,/ 3, 4, 5, 3,/ 6, 4, 7, 5,/ 6, 7, 1)
1
2
3
4
5
6
7
1
0
1
1
1
1
1
1
2
0
1
1
1
1
1
3
0
1
1
1
1
4
0
1
1
1
5
0
1
1
6
0
1
7
0
int x[] = { 1, 1, 1, 1, 1, 1, / 1, 1, 1, 1, 1, / 1, 1, 1, 1, / 1, 1, 1, 1, 1, 1 };
int x[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
Euler Cycle C++ Code
#include <stdio.h>
#include <stack.h>
int Matrix[100][100];
int n;
void Create() {
int i, j, k1; n = 7; k1 = 0;
int x[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
for (i = 0; i < n; i++)
for (j = i+1; j < n; j++) {
57

Matrix[j][i] = Matrix[i][j] = x[k1]; k1++; }


for (i = 0; i < n; i++)
Matrix[i][i] = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
printf ("%5d", Matrix[i][j]);
printf("\n");
} printf("\n");
}
/* chu trinh Euler bang phuong phap stack
1. Tim duong di tai 1 diem: Kiem tra xem so bac le co = 2 khong
2. Tim duong di tai tat cac cac diem : dung phuong phap de quy */
int KiemTra() {
int i, j, d, s; d = 0;
for(i = 0; i < n; i++) {
s = 0;
for (j = 0; j < n; j++)
s += Matrix[i][j];
if (s % 2 != 0) d++; // Kiem tra xem la so dinh bac co chan hay khong neu
khong thi d++
}
if (d > 0)
return (false);
return (true);
}
void Euler() {
int dCE = -1; // vi xet khoang tu 0 -> n-1;
stack <int> myStack;
int CE[100]; // Cycle Euler dung de luu nhung phan tu lay tu ngan xep.
int v, x, u; u = 0; // Chon u = 0 de ta lay diem bat dau la so 1.
myStack.push(u);
do {
v = myStack.top(); // chon x lam phan tu dau.
x = 0;
while (x < n && Matrix[v][x] == 0)
x++;
if (x >= n) {
dCE++; CE[dCE] = v;
myStack.pop();
}
else {
myStack.push(x);
Matrix[v][x] = 0; Matrix[x][v] = 0; // xoa cac canh di
}
} while (!myStack.empty());
58

printf ("Co chu trinh Euler \n");


for (int i = dCE; i>= 0; i--)
printf ("%5d", CE[i]+1);
}
int main() {
Create();
if(KiemTra())
Euler();
else
printf ("Khong co chu trinh Euler \n");
}
with(GraphTheory):
with(RandomGraphs):
G := CompleteGraph(5);
DrawGraph(G);

IsEulerian(G, T);
T
Trail(1, 2, 3, 1, 4, 2, 5, 3, 4, 5, 1);
1
2
3
4
5
1
0
1
1
1
1
2
0
1
1
1
3
0
1
1
4
0
1
5
0
int x[] = { 1, 1, 1, 1, / 1, 1, 1, / 1, 1, 1};
int x[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
Chu trnh Hamilton
Quy tc xc nh th Hamilton
59

- Rule 1: Tt c cc cnh k vi 1 nh bc 2 phi trong H.


- Rule 2: Ko c chu trnh con no (chu trnh c chiu di nh hn n) c to
thnh trong qu trnh xy dng H.
- Rule 3: Khi chu trnh Hamiltom m ta ang xy dng i qua nh i th xa tt c
cnh k vi i m cha i qua. iu ny c th cho ta 1 s nh bc 2 v ta li c th
dng quy tc 1.
- Rule 4: Ko c nh c lp hay cnh treo no c to nn sau khi dng quy tc 3.
Hamilton Maple Code
with(GraphTheory):
with(SpecialGraphs):
with(RandomGraphs):
Hamilton := proc(G::Graph)
global n, M, Road, check, Kt; local i, k, E;
n := NumberOfVertices(G); E := Graph(n);
DrawGraph(G); check := false;
M := AdjacencyMatrix(G); Road := array(1..n); k := 1;
for i from 1 to n do
if check = true then
break;
else
Kt := {i}; Road[1] := i; Browse(i, 1);
end if;
end do;
if check = false then
error "Ko ton tai duong di Hamilton";
else
for i from 1 to n-1 do
AddEdge( E, { Road[i], Road[i+1] } );
end do;
HighlightEdges(G, E, red);
print( DrawGraph(G) ); print(Road);
end if;
end proc:
Browse := proc(x0, k)
global M, Road, Kt, check; local i;
if k = n then
check := true; end if;
if check = false then
for i from 1 to n do
if i Kt and M(x0, i) != 0 then
60

Kt := Kt union {i};
if check = false then Road[k+1] := i; end if;
Browse(i, k+1); Kt := Kt \ {i};
end if;
end do;
end if;
end proc:
G1 := PetersenGraph(); AddEdge(G1, {1, 3});
Hamilton(G1);

> with(GraphTheory):
with(SpecialGraphs):
G := PetersenGraph();
AddEdge(G, {1, 3});
DrawGraph(G);

IsHamiltonian(G, 'T');
T = { 1, 2, 9, 8, 5, 4, 10, 6, 7, 3, 1 }
n

8
61

10

h
1
2
3
4
5
6
7
8
9
0

1
0

1
1
0

0
0
1
0

1
0
0
1
0

1
0
0
0
0
0

0
0
1
0
0
1
0

0
0
0
0
1
0
1
0

0
1
0
0
0
0
0
1
0

0
0
0
1
0
1
0
0
1
0

int x[] = { 1, 1, 0, 1, 1, 0, 0, 0, 0, / 1, 0, 0, 0, 0, 0, 1, 0, / 1, 0, 0, 1, 0, 0, 0, / 1, 0, 0, 0,
0, 1, / 0, 0, 1, 0, 0, / 1, 0, 0, 1, / 1, 0, 0, 1, 0, 1 };
int x[] = { 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,
0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1 };
Code Hamilton C++
#include <stdio.h>
#define max 20
int a[max][max];
int Mark[max], c[max];
int n;
void Create() {
int i, j, k1; n = 10; k1 = 0;
int x[] = { 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0,
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1 };
for (i = 0; i < n; i++)
for (j = i+1; j < n; j++) {
a[j][i] = a[i][j] = x[k1]; k1++; }
for (i = 0; i < n; i++)
a[i][i] = 0;
for (i = 0; i < n; i++) Mark[i] = 0;
c[0] = 0; Mark[0] = 1; // Xuat phat tu dinh 0.
}
void ShowPath() {
for (int k = 0; k < n; k++)
printf ("%4d", c[k]+1); // In ra s hiu nh + 1
printf ("%4d \n", c[0]+1);
}
void Hamilton(int k) {
for (int i = 0; i < n; i++)
if (Mark[i] == 0 && a [ c[k-1] ] [i] != 0) {
Mark[i] = 1; c[k] = i;

62

if (k == n-1) {
if (a [ c[k]] [c[0] ] != 0) ShowPath();
}
else Hamilton(k+1);
Mark[i] = 0;
}
}
int main() {
Create();
Hamilton(1);
}
void Hamilton(int k) {
for (int i = 0; i < n; i++)
if (Mark[i] == 0 && a [ c[k-1] ] [i]) { // Nu nh k cha duyt n v c ni
vi nh va c ghi nhn trc (th j-1, s hiu l c[j-1])
Mark[i] = 1; c[k] = i; // Xem nh duyt nh k v n l nh th j theo trnh
t ghi nhn.
if (k == n-1) { // Nu ghi nhn s nh
if (a [c[k]] [c[0]] != 0) ShowPath(); // Nu nh cui c ni vi nh u
tin th hin th chu trnh.
}
else Hamilton(k+1); // Nu cha ghi nhn n nh th quy tm nh
th j+1.
Mark[i] = 0; // Quay lui chnh l ch ny y.
}
}

IsHamiltonian(G, 'T');
T = { 1, 2, 9, 8, 5, 4, 10, 6, 7, 3, 1 }

63

- Bt u t nh 1, ly cnh {1, 2}, {1, 3}, xa cnh {1, 6}, {1, 5} (do ly 2
cnh k vi nh 1). Ly {2, 3} s to thnh chu trnh {1, 2, 3}, xa cnh {2, 3}.
G := DeleteEdge(G, { {1, 6}, {1, 5}, {2, 3} } );
DrawGraph(G);

- Cc nh 5, 6 tr thnh nh bc 2, ly cnh {5, 4}, {5, 8}, {6, 7}, {6, 10}.
- Ly cnh {2, 9} c lin thng. Ta c chu trnh { 9, 10, 6, 7, 8, 9 }; Trong ta
ly cnh {6, 7}, {6, 10} vy b cnh {7, 8}.
G := DeleteEdge(G, {7, 8} );
DrawGraph(G);

- Gi ta c nh 7 v nh 8 l nh bc 2. Ly cnh {7, 6}, {7, 3}, {8, 5}, {8, 9}.


- Ta c chu trnh {1, 3, 4, 5, 8, 9, 2, 1} bc 7 nh hn 10, vy xa cnh {3, 4} v
cc cnh khc add.
- Ta cng c chu trnh { 9, 10, 6, 7, 3, 1, 2, 9} bc 7 nh hn 10, vy xa cnh
{9, 10} v cc cnh khc add.
G := DeleteEdge(G, { {3, 4}, {9, 10} } );
64

DrawGraph(G);

Chu trnh 2:
> with(GraphTheory):
with(SpecialGraphs):
G := PetersenGraph();
AddEdge(G, {1, 3});
DrawGraph(G);

IsHamiltonian(G, 'T');
T = { 1, 2, 9, 8, 5, 4, 10, 6, 7, 3, 1 }
- Bt u t nh 1, ly cnh {1, 2}, {1, 3}, xa cnh {1, 6}, {1, 5} (do ly 2
cnh k vi nh 1). Ly {2, 3} s to thnh chu trnh {1, 2, 3}, xa cnh {2, 3}.
G := DeleteEdge(G, { {1, 6}, {1, 5}, {2, 3} } );
DrawGraph(G);

65

- Cc nh 5, 6 tr thnh nh bc 2, ly cnh {5, 4}, {5, 8}, {6, 7}, {6, 10}.
- Ly cnh {2, 9} c lin thng. Ta c chu trnh { 9, 10, 6, 7, 8, 9 }; Trong ta
ly cnh {6, 7}, {6, 10} vy b cnh {8, 9}.
G := DeleteEdge(G, { {1, 6}, {1, 5}, {2, 3}, {8, 9} } );
DrawGraph(G);

- Gi ta c nh 8 v nh 9 l nh bc 2. Ly cnh {8, 5}, {8, 7}, {9, 2}, {9, 10}.


- Ta c chu trnh {3, 4, 5, 8, 7, 3} bc 5 nh hn 10, vy xa cnh {7, 3} v cc
cnh khc add.
G := DeleteEdge(G, { {1, 6}, {1, 5}, {2, 3}, {8, 9}, {3, 7} } );
DrawGraph(G);

66

- Ta cn chu trnh { 6, 7, 8, 5, 4, 10, 6 } bc 6 nh hn 10, vy xa cnh {4, 10}.


G := DeleteEdge(G, { {1, 6}, {1, 5}, {2, 3}, {8, 9}, {3, 7}, {4, 10} } );
DrawGraph(G);

- Ta c chu trnh { 1, 2, 9, 10, 6, 7, 8, 5, 4, 3, 1 }.


Dijsktra 2
> with(GraphTheory):
G := Graph( { [{1, 3}, 7], [{1, 4}, 3], [{1, 6}, 5], [{1, 7}, 8], [{2, 4}, 4], [{3, 2},
6], [{3, 4}, 2], [{3, 6}, 8], [{3, 7}, 5], [{4, 5}, 6], [{5, 7}, 4] } );
DrawGraph(G);

67

Tm ng i ngn nht t nh 2 n cc nh cn li:


2 3 = 6; 2 4 = 4; 2 4 3 = 6; 2 3 = 6
2 3 1 = 13; 2 4 1 = 7; 2 1 = 7
2 3 6 = 14;
2 3 7 = 11;
2 4 5 = 10;
Bc

nh 1

nh 3

nh 4

nh 5

nh 6

nh 7

1
2
3
4
5
6
7
Kt qu

(, )
(7, 4)
(7, 4)
(7, 4)

(6, 2)
(6, 2)
(6, 2)

(4, 2)
(6, 2)

(, )
(10, 4)
(10, 4)
(10, 4)
(10, 4)

(7, 4)

(6, 2)

(6, 2)

(10, 4)

(, )
(, )
(14, 3)
(14, 3)
(14, 3)
(14, 3)
(14, 3)
(14, 3)

(, )
(, )
(11, 3)
(11, 3)
(11, 3)
(11, 3)

(11, 3)

ng i ngn nht t nh 2 n nh 1 l 7 v i qua nh 4.


ng i ngn nht t nh 2 n nh 3 l 6 v i qua nh 2.
ng i ngn nht t nh 2 n nh 4 l 6 v i qua nh 2.
ng i ngn nht t nh 2 n nh 5 l 10 v i qua nh 4.
ng i ngn nht t nh 2 n nh 6 l 14 v i qua nh 3.
ng i ngn nht t nh 2 n nh 7 l 11 v i qua nh 3.
Tm cy khung ti thiu ca G bng thut ton Prims

68

nh
chn
2
4
3
1
5
7
6

- Bt u t nh 1, cc nh k vi nh 1 l 3, 4, 6, 7. Cnh {1, 4} c di 3 l
min, thm cnh {1, 4} vo T.
- Cc nh k vi nh 1, 4 l 3, 6, 7, 2, 5. Cnh {4, 3} c di 2 l min, thm
cnh {4, 3} vo T.
- Cnh {4, 2} c di 4 l min, thm cnh {4, 2} vo T.
- Cnh {1, 6} c di 5 l min, thm cnh {1, 6} vo T.
- Cnh {3, 7} c di 5 l min, thm cnh {3, 7} vo T.
- Cnh {7, 5} c di 4 l min, thm cnh {7, 5} vo T. 6 cnh.
- T = { {1, 4}, {4, 3}, {4, 2}, {1, 6}, {3, 7}, {7, 5} }

C th no di chuyn con m trn mt bn c vua 4x4 i qua tt c cc ca bn c,


mi mt ln v tr v xut pht khng?
th Hamilton
1
2
3
4
5
6
7
8
9 10 11 12
13 14 15 16
G ko Hamilton v c chu trnh con nh hn 16: {7, 16, 10, 8, 2, 9, 7}

69

'

70

Вам также может понравиться