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

Basic Graph Algorithms

Programming Puzzles and Competitions


CIS 4900 / 5920
Spring 2009

Outline
Introduction/review of graphs
Some basic graph problems &
algorithms
Start of an example question from
ICPC07 (Tunnels)

Relation to Contests
Many programming contest problems
can be viewed as graph problems.
Some graph algorithms are
complicated, but a few are very
simple.
If you can find a way to apply one of
these, you will do well.

How short & simple?


int [][] path = new int[edge.length][edge.length];
for (int i =0; i < n; i++)
for (int j = 0; j < n; j++)
path[i][j] = edge[i][j];
for (int k = 0; k < n; k++)
for (int i =0; i < n; i++)
for (int j = 0; j < n; j++)
if (path[i][k] != 0 && path[k,j] != 0) {
x = path[i][k] + path[k][j];
if ((path[i,j] == 0) || path[i][j] > x) path[i][j] = x;
}

Directed Graphs
G = (V, E)
V = set of vertices

(a.k.a. nodes)

E = set of edges
(ordered pairs of nodes)

Directed Graph
V = { a, b, c, d }
E = { (a, b), (c, d), (a, c), (b, d), (b, c) }
b
a

d
c

Undirected Graph
V = { a, b, c, d }
E = { {a, b}, {c, d}, {a, c}, {b, d}, {b, c} }
b
a

d
c

Undirected Graph as Directed


V = { a, b, c, d }
E = { (a, b), (b,a),(c,d),(d,c),(a,c),(c,a),
(b,d),(d,b),(b,c)(c,b)}
b
a

d
c

Can also be viewed as symmetric directed graph, replacing


each undirected edge by a pair of directed edges .

Computer Representations

Edge list
Hash table of edges
Adjacency list
Adjacency matrix

Edge List
0 1
0 2

1
3

0
2

2 3
Often corresponds to the input format for contest problems.
Container (set) of edges may be used by
algorithms that add/delete edges.

Adjacency List
with two
arrays:

1
3

0
2

with pointers
& dynamic
allocation:

0
1
2
3
4

Can save space and time if graph is sparse.

0 1 2 3 4
0 2 4 4 4
0 1 2 3 4
1 2 2 3 3
1 2
2 3
3

Hash Table (Associative Map)


H(0,1)
H(1,2)
etc.

1
3

0
2

good for storing information about nodes or edges, e.g., edge weight

Adjacency/Incidence Matrix
A[i][j] = 1 (i,j) i E
A[i][j] = 0 otherwise

3
2

1 2 3

0 0 1 1 0

1
0

1 0 0 1 1
2 0 0 0 1
3 0 0 0 0

a very convenient representation for simple coding of algorithms,


although it may waste time & space if the graph is sparse.

Some Basic Graph Problems


Connectivity, shortest/longest path
Single source
All pairs: Floyd-Warshall Algorithm
dynamic programming, efficient, very simple

MaxFlow (MinCut)
Iterative flow-pushing algorithms

Floyd-Warshall Algorithm
Assume edgeCost(i,j) returns the cost of the edge from i to j
(infinity if there is none), n is the number of vertices, and
edgeCost(i,i) = 0
int path[][]; // a 2-D matrix.
// At each step, path[i][j] is the (cost of the) shortest path
// from i to j using intermediate vertices (1..k-1).
// Each path[i][j] is initialized to edgeCost (i,j)
// or if there is no edge between i and j.
procedure FloydWarshall ()
for k in 1..n
for each pair (i,j) in {1,..,n}x{1,..,n}
path[i][j] = min ( path[i][j], path[i][k]+path[k][j] );
* Time complexity: O(|V|3 ).

Details
Need some value to represent pairs of
nodes that are not connected.
If you are using floating point, there is a
value for which arithmetic works
correctly.
But for most graph problems you may want
to use integer arithmetic.
Choosing a good value may simplify code
When and why to use F.P. vs. integers is an interesting side discussion.

Example

Suppose we use path[i][j] == 0 to


indicate lack of connection.
if (path[i][k] != 0 && path[k,j] != 0) {
x = path[i][k] + path[k][j];
if ((path[i,j] == 0) || path[i][j] > x) path[i][j] = x;
}

How it works

path[i][k]

path[i][j]
paths that go
though only
nodes 0..k-1

path[k,j]

Correction
In class, I claimed that this algorithm could be adapted to find
length of longest cycle-free path, and to count cycle-free
paths.
That is not true.
However there is a generalization to find the maximum flow
between points, and the maximum-flow path:
for k in 1,..,n
for each pair (i,j) in {1,..,n}x{1,..,n}
maxflow[i][j] = max (maxflow[i][j]
min (maxflow[i][k], maxflow[k][j]);

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