Documentos de Académico
Documentos de Profesional
Documentos de Cultura
University of Tehran
Faculty of Engineering
Mohsen Vakilian
m.vakilian@ece.ut.ac.ir
November 1, 2006
Contents
1 Probable Mistakes
2 Skeleton
3 Java I/O
7
7
7
8
8
8
13
13
13
13
14
8 Dynamic Programming
8.1 Longest Increasing Subsequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
15
18
18
18
18
18
19
19
19
19
19
20
20
20
21
21
21
21
21
21
24
24
24
24
25
25
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
26
26
26
26
11 String Matching
11.1 Naive String Matching Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11.2 Rabin-Karp String Matching Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11.3 The Knuth-Morris-Pratt Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
29
29
30
12 Geometric Algorithms
12.1 Trigonometric Functions . . . . . .
12.2 Distances . . . . . . . . . . . . . .
12.3 Intersection . . . . . . . . . . . . .
12.3.1 Point of Intersection of Two
12.4 Projection . . . . . . . . . . . . . .
12.5 Reflection . . . . . . . . . . . . . .
12.6 Area of polygon . . . . . . . . . . .
12.7 Transformations . . . . . . . . . .
12.7.1 Rotation . . . . . . . . . . .
12.7.2 Line Reflection . . . . . . .
12.7.3 Scale . . . . . . . . . . . . .
12.7.4 Perpendicular Projection .
12.7.5 Amood Monasef . . . . . .
12.8 Point in Triangle . . . . . . . . . .
12.9 Convex Hull (Grahams scan) . . .
. . . .
. . . .
. . . .
Lines
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
32
32
36
37
37
39
39
39
39
39
40
40
40
40
40
40
13 Libraries
13.1 STL . . . . . . . . . . .
13.1.1 bitset . . . . . .
13.1.2 string . . . . . .
13.2 Character Classification
13.3 Streams . . . . . . . . .
13.3.1 ios-base . . . . .
13.3.2 File Streams . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
42
42
42
42
42
42
43
43
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Chapter 1
Probable Mistakes
Should it really be a map or a multimap?
less than operator should impose a total ordering for the map to work.
Resolve all the compiler warnings. Pay attention to type cast conversions in STL size().
A two dimensional array cannot be initialized by fill().
The predicate passed to the set template must have a default constructor.
EP S 1e 14
Be careful about the range of arrays. [] is your enemy!
Chapter 2
Skeleton
// S k e l e t o n . cpp
#include <c a s s e r t >
#include <c s t d i o >
#include <c s t d l i b >
#include <fstream>
#include <i o s t r e a m >
#include <iomanip>
#include <string>
#include <sstream >
#include <iterator >
#include <vector>
#include <l i s t >
#include <set>
#include <multiset>
#include <map>
#include <multimap>
#include <a l g o r i t h m >
#include <cmath>
#include <c ct ype >
#include <ctime>
#include <s t a c k >
#include <queue>
using namespace std ;
//#d e f i n e NDEBUG
#i f n d e f
#define
#define
#e l s e
#define
#define
#endif
NDEBUG
D ( args ) args
D P ( exp ) { c e r r << #exp << = [ << ( exp ) << ] \ n << f l u s h ; }
D ( args )
D P ( exp )
Chapter 3
Java I/O
BufferedReader fin = new BufferedReader (new FileReader ( X. i n ) ) ;
PrintWriter fout = new PrintWriter ( X. out ) ;
int n = Integer . parseInt ( fin . readLine ( ) ) ;
fout . close ( ) ;
System . exit ( 0 ) ;
//
BufferedReader fin = new BufferedReader (new InputStreamReader ( System . in ) ) ;
StringTokenizer toker ;
String line ;
while ( ( line = fin . readLine ( ) . trim ( ) ) != null ) {
toker = new StringTokenizer ( line ) ;
int m = Integer . parseInt ( toker . nextToken ( ) ) ;
int n = Integer . parseInt ( toker . nextToken ( ) ) ;
}
Chapter 4
int main ( ) {
clock_t start = clock ( ) ;
//Do s o m e t h i n g
clock_t ends = clock ( ) ;
cout << Running Time : << ( double ) ( ends start ) / CLOCKS_PER_SEC << endl ;
return 0 ;
}
4.2
Chapter 5
#include <cmath>
using namespace std ;
//The S i e v e o f E r a t o s t h e n e s
// This code has a bug ! Can you f i n d i t o u t ?
bool sieve ( int n ) {
bool p = new bool [ n + 1 ] ;
f o r ( int i = 0 ; i < n + 1 ; i++)
p [ i ] = true ;
p [ 0 ] = false ;
p [ 1 ] = false ;
int m = ( int ) sqrt ( ( double ) n ) ;
f o r ( int i = 2 ; i <= m ; i++)
if (p [ i ])
f o r ( int k = i i ; k <= n ; k += i )
p [ k ] = false ;
return p ;
}
5.2
Big Integer
while ( carry ) {
DoubleElementType accu ;
accu = digits [ i ] ;
accu += carry ;
digits [ i ] = ( ElementType ) ( accu ) ;
carry = ( accu >> WordBits ) ;
i++;
}
Normalize ( ) ;
}
i n l i n e void BigInteger : : MultWord ( PlatWord aFactor ) {
unsigned i ;
digits . push_back ( 0 ) ;
DoubleElementType carry = 0 ;
f o r ( i = 0 ; i < digits . size ( ) ; i++) {
DoubleElementType accu ;
accu = digits [ i ] ;
accu = aFactor ;
accu += carry ;
digits [ i ] = ( ElementType ) ( accu ) ;
carry = ( accu >> WordBits ) ;
}
assert ( carry == 0 ) ;
Normalize ( ) ;
}
i n l i n e void BigInteger : : DivideWord ( PlatDoubleWord aNumber , PlatDoubleWord &aCarry ) {
PlatDoubleWord carry =0;
int i ;
int nr = digits . size ( ) ;
f o r ( i= nr 1 ; i >= 0 ; i) {
PlatDoubleWord word = ( ( carry WordBase ) + ( ( PlatDoubleWord ) ( digits [ i ] ) ) ) ;
PlatWord digit = ( PlatWord ) ( word / aNumber ) ;
PlatWord newCarry = ( PlatWord ) ( word % aNumber ) ;
digits [ i ] = digit ;
carry= newCarry ;
}
// c a r r y now i s t h e remainder
aCarry = carry ;
Normalize ( ) ;
}
10
11
string result ;
BigInteger number ( t h i s ) ;
while ( number != zero ) {
PlatDoubleWord digit ;
number . DivideWord ( 1 0 , digit ) ;
result . push_back ( digit ) ;
}
int i , nr = result . size ( ) ;
f o r ( i = ( nr>>1) 1 ; i >= 0 ; i ) {
char swp = result [ i ] ;
result [ i ] = 0 + result [ result . size ( ) i 1 ] ;
result [ result . size ( )i 1] = 0 + swp ;
}
i f ( nr & 1 ) result [ ( nr >> 1 ) ] += 0 ;
i f ( negative ) result . insert ( 0 , , 0 , 1 ) ;
return result ;
}
int main ( int argc , char argv ) {
#define X 123456789
#define Y 23456789
#define Z 456789
BigInteger x ( X ) ;
BigInteger y ( Y ) ;
BigInteger z ( Z ) ;
BigInteger result ;
result . MultiplyAdd ( x , y ) ;
result . Add ( z ) ;
printf ( %s %s + %s = \n\ t%s \n , X , Y , Z , result . ToString ( ) . c_str ( ) ) ;
/ In> 123456789 23456789 + 456789
Out> 2895899850647310 /
BigInteger yacasResult ( 2895899850647310 ) ;
printf ( Yacas s a y s \n\ t%s \n , yacasResult . ToString ( ) . c_str ( ) ) ;
return 0 ;
}
12
Chapter 6
Next-Permutation(a)
1 a1 a2 an is a permutation of {1, 2, . . . , n} not equal to n n 1 2 1
2 j n1
3 while aj > aj+1
4
do j j 1
5 j is the largest subscript with aj < aj+1
6 kn
7 while aj > ak
8
do k k 1
9 ak is the smallest integer greater than aj to the right of aj .
10 exchange aj ak
11 r n
12 s j + 1
13 while r > s
14
do exchange ar as
15
r r1
16
ss+1
17 This puts the tail end of the permutation after the jth position in increasing order.
6.2
Next-Bit-String(b)
1 bn1 bn2 . . . b1 b0 is a bit string not equal to 11 . . . 11
2 i0
3 while bi = 1
4
do bi 0
5
ii+1
6 bi 1
6.3
Next-r-Combination(a)
1 {a1 , a2 , . . . , ar } is a proper subset of {1, 2, . . . , n}
not equal to {n r + 1, . . . , n} with a1 < a2 < < ar .
2 ir
3 while ai = n r + i
4
do i i 1
5 ai ai + 1
6 for j i + 1 to r
7
do aj ai + j i
13
Chapter 7
14
Chapter 8
Dynamic Programming
8.1
else {
length [ i ] = max1 + 1 ;
for ( k = 0 ; k < max1 ; k++) {
data [ i ] [ k ] = data [ index1 ] [ k ] ;
}
data [ i ] [ max1 ] = i ;
}
}
//Now d a t a i s c o m p l e t e
int max = 0 ;
int index = 1;
f o r ( i = 0 ; i < n ; i++) {
i f ( length [ i ] > max ) {
max = length [ i ] ;
index = i ;
}
}
vector < int >ans ;
f o r ( j = 0 ; j < length [ index ] ; j++) {
ans . push_back ( data [ index ] [ j ] ) ;
}
return ans ;
}
};
int input [ ] = { 5 , 1 , 6 , 7 , 3 , 4 , 5 } ;
int main ( ) {
Sequences z ;
vector <int> x ;
int i , j ;
f o r ( i = 0 ; i < s i z e o f ( input ) / s i z e o f ( int ) ; i++)
x . push_back ( input [ i ] ) ;
vector <int> ans ;
ans = z . LongestIncreasing ( x ) ;
int n = x . size ( ) ;
printf ( \ nInput : ) ;
f o r ( i = 0 ; i < n ; i++)
printf ( %d , x [ i ] ) ;
f o r ( i = 0 ; i < n ; i++) {
printf ( \ nending a t [%d ] = %d , i , x [ data [ i ] [ 0 ] ] ) ;
f o r ( j = 1 ; j < length [ i ] ; j++)
printf ( , %d , x [ data [ i ] [ j ] ] ) ;
}
printf ( \n answer i s ) ;
int m = ans . size ( ) ;
f o r ( i = 0 ; i < m ; i++)
printf ( %d , x [ ans [ i ] ] ) ;
return 0 ;
16
17
Chapter 9
The breadth-first-search procedure BFS below assumes that the input graph G = (V, E) is represented using adjacency
lists.
9.1.1
Pseudocode
BFS(G, s)
1 for each vertex u V [G] {s}
2
do color[u] white
3
d[u]
4
[u] nil
5 color[s] gray
6 d[s] 0
7 [s] nil
8 Q
9 Enqueue(Q, s)
10 while Q 6=
11
do u Dequeue(Q)
12
for each v Adj[u]
13
do if color[v] = white
14
then color[v] gray
15
d[v] d[u] + 1
16
[v] u
17
Enqueue(Q, v)
18
color[u] black
Print-Path(G, s, v)
1 if v = s
2
then print s
3
else if [v] = nil
4
then print no path from s to v exists
5
else Print-Path(G, s, [v])
6
print v
9.1.2
Analysis
Because the adjacency list of each vertex is scanned at most once, the total time spent in adjacency lists is O(E). The
overhead for initialization is O(V ), and thus the total running time of BFS is O(V + E).
9.1.3
A depth-first forest classifies the edges of a graph into tree, back, forward, and cross edges. A breadth-first tree can
also be used to classify the edges reachable from the source of the search into the same four categories.
1. Prove that in a breadth-first search of an undirected graph, the following properties hold:
18
9.2
Vertex u is white before time d[u], gray between time d[u] and time f [u], and black thereafter. The variable time
is a global variable that we use for timestamping.
9.2.1
Pseudocode
DFS(G)
1 for each vertex u V [G]
2
do color[u] white
3
[u] nil
4 df sT ime 0
5 for each vertex u V [G]
6
do if color[u] = white
7
then DFS-Visit(u)
DFS-Visit(u)
1 color[u] gray
White vertex u has just been discovered.
2 d[u] df sT ime df sT ime + 1
3 for each v Adj[u]
Explore edge (u, v).
4
do if color[v] = white
5
then [v] u
6
DFS-Visit(v)
7 color[u] black
Blacken u; it is finished.
8 f [u] df sT ime df sT ime + 1
9.2.2
Analysis
9.2.3
Parenthesis theorem
In any depth-first search of a (directed or undirected) graph G = (V, E), for any two vertices u and v, exactly one of
the following three conditions holds:
the intervals [d[u], f [u]] and [d[v], f [v]] are entirely disjoint, and neither u nor v is a descendant of the other in
the depth-first forest,
the interval [d[u], f [u]] is contained entirely within the interval [d[v], f [v]], and u is a descendant of v in a
depth-first tree, or
the interval [d[v], f [v]] is contained entirely within the interval [d[u], f [u]], and v is a descendant of u in a
depth-first tree, or
9.2.4
Classification of edges
We can define four edge types in terms of the depth-first forest G produced by a depth-first search on G.
1. Tree edges are edges in the depth-first forest G . Edge (u, v) is a tree edge if v was first discovered by exploring
edge (u, v).
19
2. Back edges are those edges (u, v) connecting a vertex u to an ancestor v in a depth-first tree. Self-loops, which
may occur in directed graphs, are considered to be back edges.
3. Forward edges are those nontree edges (u, v) connecting a vertex u to a descendant v in a depth-first tree.
4. Cross edges are all other edges. They can go between vertices in the same depth-first tree, as long as one
vertex is not an ancestor of the other, or they can go between vertices in different depth-first trees.
The DFS algorithm can be modified to classify edges as it encounters them. The key idea is that each edge (u, v)
can be classified by the color of the vertex v that is reached when the edge is first explored (except that forward and
cross edges are not distinguished):
1. white indicates a tree edge,
2. gray indicates a back edge, and
3. black indicates a forward or cross edge.
In an undirected graph, there may be some ambiguity in the type classification, since (u, v) and (v, u) are really the
same edge. In such a case, the edge is classified as the first type in the classification list that applies. Equivalently, the
edge is classified according to whichever of (u, v) or (v, u) is encountered first during the execution of the algorithm.
Edge (u, v) is
1. a tree edge or forward edge if and only if d[u] < d[v] < f [v] < f [u],
2. back edge if and only if d[v] < d[u] < f [u] < f [v], and
3. a cross edge if and only if d[v] < f [v] < d[u] < f [u].
9.2.5
Theorem
In a depth-first search of an undirected graph G, every edge of G is either a tree edge or a back edge.
9.3
Topological Sort
A topological sort of a dag G = (V, E) is a linear ordering of all its vertices such that if G contains an edge (u, v),
then u appears before v in the ordering.
9.3.1
Pseudocode
20
9.3.2
Analysis
9.4
A strongly connected component of a directed graph G = (V, E) is a maximal set of vertices C V such that for
every pair of vertices u and v in C, we have both u ; v and v ; u; that is, vertices u and v are reachable from each
other.
9.4.1
Pseudocode
Strongly-Connected-Components(G)
1 call DFS(G) to compute finishing times f [u] for each vertex u
2 compute GT
3 call DFS(GT ), but in the main loop of DFS, consider the vertices
in order of decreasing f [u] (as computed in line 1)
4 output the vertices of each tree in the depth-first forest formed in line 3 as a
separate strongly connected component
9.4.2
Analysis
9.5
Let G = (V, E) be a connected, undirected graph. An articulation point of G is a vertex whose removal disconnects
G. A bridge of G is an edge whose removal disconnects G. A biconnected component of G is a maximal set of
edges such that any two edges in the set lie on a common simple cycle. We can determine articulation points, bridges,
and biconnected components using depth-first search. Let G = (V, E ) be a depth-first tree of G.
9.5.1
Articulation points
1. Prove that the root of G is an articulation point of G if and only if it has at least two children in G .
2. Let v be a nonroot vertex of G . Prove that v is an articulation point of G if and only if v has a child s such
that there is no back edge from s or any descendant of s to a proper ancestor of v.
3. Let
low[v] = min
d[v],
d[w] : (u, w) is a back edge for u = v or some descendant u of v.
INF 1000000000
MAX 1000
NOPAR 1
WHITE 0
GRAY 1
BLACK 2
21
int dfsTime ;
// These a r e used t o d e l e t e and r e s t o r e v e r t i c e s
bool deleted [ MAX ] ;
int backup [ MAX ] ;
int low [ MAX ] , nchilds [ MAX ] , iscut [ MAX ] ;
void init ( ) {
int i , j ;
f o r ( i = 0 ; i < MAX ; ++i )
f o r ( j = 0 ; j < MAX ; ++j )
g [ i ] [ j ] = 0;
n = 0;
fill ( deleted , deleted + MAX , true ) ;
}
void readNext ( ) {
/
Remember t o
1 . S e t n ( t h e number o f v e r t i c e s )
2 . Keep t h e symmetry o f t h e a d j a c e n c y m a t r i x
3 . S e t t h e d e l e t e d [ ] i f i t s needed
/
// . . .
}
// Returns t h e a d j a c e n t s o f u
vector<int> adjs ( int u ) {
vector<int> a ;
f o r ( int v = 1 ; v <= n ; ++v ) {
i f ( deleted [ v ] ) continue ;
i f ( g [ u ] [ v ] >= 1 )
a . push_back ( v ) ;
}
return a ;
}
void delVertex ( int u ) {
f o r ( int v = 1 ; v <= n ; ++v )
backup [ v ] = g [ u ] [ v ] ;
f o r ( int v = 1 ; v <= n ; ++v )
g [ u ] [ v ] = g [ v ] [ u ] = 0;
deleted [ u ] = true ;
}
void restoreVertex ( int u ) {
f o r ( int v = 1 ; v <= n ; ++v )
g [ u ] [ v ] = g [ v ] [ u ] = backup [ v ] ;
deleted [ u ] = f a l s e ;
}
void dfsVisit ( int u ) {
color [ u ] = GRAY ;
d [ u ] = ++dfsTime ;
22
23
calc_nchilds ( ) ;
// v i s an a r t i c u l a t i o n p o i n t i f f v has a c h i l d s such t h a t t h e r e i s no b a c k e d g e
from s or any d e s c e n d a n t o f s t o a p r o p e r a n c e s t o r o f v .
f o r ( int v = 1 ; v <= n ; ++v ) {
i f ( p [ v ] == NOPAR ) continue ;
i f ( low [ v ] >= d [ p [ v ] ] )
iscut [ p [ v ] ] = true ;
}
//The r o o t o f t h e DFS t r e e i s an a r t i c u l a t i o n p o i n t i f f
children .
f o r ( int v = 1 ; v <= n ; ++v ) {
i f ( deleted [ v ] ) continue ;
i f ( p [ v ] != NOPAR ) continue ;
i t has a t l e a s t two
i f ( nchilds [ v ] >= 2 )
iscut [ v ] = true ;
else
iscut [ v ] = f a l s e ;
}
}
9.5.2
1. Prove that an edge of G is a bridge if and only if it does not lie on any simple cycle of G.
2. Show how to compute all the bridges of G in O(E) time.
3. Prove that the biconnected components of G partition the nonbridge edges of G.
4. Give an O(E)-time algorithm to label each edge e of G with a positive integer bcc[e] such that bcc[e] = bcc[e0 ] if
and only if e and e0 are in the same biconnected component.
Solution. At first, we remove all bridges, then each call to DFS-Visit returns a biconnected component.
9.6
9.6.1
Floyd-Warshall(W )
1 n rows[W ]
2 DW
3 for k 1 to n
4
do for i 1 to n
5
do for j 1 to n
6
do dij min(dij , dik + dkj )
7 return D
9.7
Eulerian Tours
An eulerian trail in a digraph (or graph) is a trail containing all edges. An eulerian circuit is a closed trail
containing all edges. A digraph is eulerian if and only if it has an eulerian circuit.
Find-Eulerian-Circuit(G)
1 circuit is a global array.
2 circuit-pos 0
3 pick an arbitrary vertex u.
4 Find-Circuit(u)
24
Find-Eulerian-Tour(G)
1 circuit is a global array.
2 circuit-pos 0
3 Pick an odd degree vertex u.
4 Find-Circuit(u)
Find-Circuit(v)
1 nextnode and visited are local arrays.
2 The path will be found in reverse order.
3 while v has neighbors
4
do Pick an arbitrary neighbor node w of node v
5
Delete-Edges(v, w)
6
Find-Circuit(w)
7 circuit[circuit-pos] v
8 circuit-pos circuit-pos +1
9.7.1
Analysis
Both of these algorithms run in O(E + V ) time, if the graph is represented by adjacency list. With larger graphs,
there is a danger of overflowing the run-time stack, so we might have to use our own stack.
9.7.2
Find-Circuit(v)
1 Push(S, v)
2 while S 6=
3
do while Top(S) has neighbors
4
do Pick an arbitrary neighbor node w of node Top(S)
5
Delete-Edges(Top(S), w)
6
Push(S, w)
7
while Top(S) has no neighbors
8
do Push(circuit, Pop(S))
25
Chapter 10
10.1
Pseudocode
10.2
Analysis
Let G be an X, Y -bigraph with n vertices and m edges. If the time for one edge exploration is bounded by a constant,
then this algorithm to find a maximum matching runs in time O(mn).
10.3
Implementation in C++
public :
bool operator ( ) ( int x ) {
return ! mark [ x ] ;
}
};
int findAugment ( ) {
while ( true ) {
SetIter it = find_if ( S . begin ( ) , S . end ( ) , IsUnmarked ( ) ) ;
i f ( it == S . end ( ) ) return 1;
int x = it ;
#i f n d e f NDEBUG
printf ( \nx=%d\n , x ) ;
#endif
vector<int> adj ;
getAdj ( x , adj ) ;
f o r ( int i = 0 ; i < adj . size ( ) ; ++i ) {
int y = adj [ i ] ;
i f ( match [ x ] == y ) continue ;
#i f n d e f NDEBUG
printf ( y=%d\n , y ) ;
#endif
i f ( match [ y ] == 1) {
parent [ y ] = x ;
return y ;
}
int w = match [ y ] ;
#i f n d e f NDEBUG
printf ( w=%d\n , w ) ;
#endif
i f ( mark [ w ] )
continue ;
parent [ y ] = x ;
parent [ w ] = y ;
T . insert ( y ) ;
S . insert ( w ) ;
}
mark [ x ] = true ;
}
}
bool augment ( ) {
#i f n d e f NDEBUG
printf ( \ naugment ( ) \n ) ;
#endif
init ( ) ;
int v = findAugment ( ) ;
i f ( v == 1) return f a l s e ;
while ( v != 1) {
match [ v ] = parent [ v ] ;
match [ parent [ v ] ] = v ;
#i f n d e f NDEBUG
printf ( %d & %d\n , v , parent [ v ] ) ;
27
#endif
v = parent [ parent [ v ] ] ;
};
return true ;
}
void init ( ) {
T . clear ( ) ;
fill ( parent . begin ( ) , parent . end ( ) , 1) ;
fill ( mark . begin ( ) , mark . end ( ) , f a l s e ) ;
S . clear ( ) ;
Fill S by U ( the set of Munsaturated vertices in X ) .
}
void solve ( ) {
mark . assign ( n , f a l s e ) ;
match . assign ( n , 1) ;
parent . assign ( n , 1) ;
while ( augment ( ) )
;
printOutput ( ) ;
}
28
Chapter 11
String Matching
Given two strings P, T, We want to check whether P is a substring of T.
11.1
As the name suggest, this algorithm search checks for all position i whether T is a substring of P. It uses a loop that
checks the condition P [0 . . m 1] = T [i . . i + m 1]. Let n := length[T ] and m := length[P ] so the complexity of this
algorithm is O((n m + 1) m).
/
n a i v e S t r i n g M a t c h (T, P)
match w h e t h e r P i s s u b s t r i n g o f T.
r e t u r n t h e s t a r t i n g i n d e x o f t h e f i r s t o c c u r e n c e o f P i n T.
/
int naiveStringMatch ( const string &T , const string &P ) {
int i , j , n , m ;
bool found ;
n = T . size ( ) ;
m = P . size ( ) ;
f o r ( i = 0 ; i <= n m ; i++) {
found = true ;
f o r ( j = 0 ; j < m ; j++)
i f ( P [ j ] != T [ i + j ] ) {
found = f a l s e ;
break ;
}
i f ( found ) return i ;
}
return 1;
}
11.2
/ RabinKarp S t r i n g Matching A l g o r i t h m
r a b i n K a r p S t r i n g M a t c h (T, P, d , q )
Assume T and P c o n s i s t o n l y a . . z and A . . Z
r a d i x d , prime q
match w h e t h e r P i s a s u b s t r i n g o f T
return the s t a r t i n g index of the f i r s t occurence of P in T
n = l e n g t h [T]
m = l e n g t h [P]
Worst Case : O( ( n m + 1) m)
Best Case : O( n + m)
29
/
#define tonum ( c ) ( c >= A && c <= Z ? c A : c a + 2 6 )
/ r e t u r n ap mod m /
int mod ( int a , int p , int m ) {
i f ( p == 0 ) return 1 ;
int sqr = mod ( a , p / 2 , m ) % m ;
sqr = ( sqr sqr ) % m ;
i f ( p & 1 ) return ( ( a % m ) sqr ) % m ;
e l s e return sqr ;
}
int rabinKarpStringMatch ( const string &T , const string &P , int d , int q ) {
int i , j , p , t , n , m , h ;
bool found ;
n = T . size ( ) ;
m = P . size ( ) ;
h = mod ( d , m 1 , q ) ;
p = t = 0;
f o r ( i = 0 ; i < m ; i++) {
p = ( d p + tonum ( P [ i ] ) ) % q ;
t = ( d t + tonum ( T [ i ] ) ) % q ;
}
f o r ( i = 0 ; i <= n m ; i++) {
i f ( p == t ) {
found = true ;
for ( j = 0 ; j < m ; j++)
i f ( P [ j ] != T [ i + j ] ) {
found = f a l s e ;
break ;
}
i f ( found ) return i ;
} else {
t = ( d ( t ( ( tonum ( T [ i ] ) h ) % q ) ) + tonum ( T [ i + m ] ) ) % q ;
}
}
return 1;
}
11.3
The running time of computeNext() is (m) and the matching time of go() is (n).
Given a pattern P [1 . . m], the prefix function for pattern P is the function next : {1, 2, . . . , m} {0, 1, . . . , m1}
such that next[state] = max{k : k < state and Pk = Pq }.
By Keeping the state, subsequent calls to go can be thought of as matching against a single long text.
P = + P ; // n e x t [ ] i s an a r r a y o f s i z e one more than t h a t o f P s .
computeNext ( P ) ; // I t s h o u l d be computed j u s t once b e f o r e go ( )
int finalState = go ( T , P , 0 ) ;
int go ( string &T , string &p , int state ) {
f o r ( int i = 0 ; i < t . size ( ) ; ++i ) {
while ( state > 0 && P [ state + 1 ] != T [ i ] )
state = next [ state ] ;
i f ( P [ state + 1 ] == T [ i ] )
++state ;
i f ( state == p . size ( ) ) {
30
// P a t t e r n o c c u r s h e r e w i t h s h i f t i m.
state = next [ state ] ;
}
}
return state ;
}
void computeNext ( string &P ) {
next [ 1 ] = 0 ;
int k = 0 ;
f o r ( int state = 2 ; state <= p . size ( ) ; ++state )
while ( k > 0 && P [ k + 1 ] != P [ state ] )
k = next [ k ] ;
i f ( P [ k + 1 ] == P [ state ] )
++k ;
next [ state ] = k ;
}
31
Chapter 12
Geometric Algorithms
12.1
Trigonometric Functions
tan
double tan ( double x ) ;
Description
This function computes the tangent of x. (which should be given in radians).
Return Value
The tangent of x. If the absolute value of x is finite but greater than or equal to 263 , the return value is 0 (since for
arguments that large each bit of the mantissa is more than ). If the value of x is infinite or NaN, the return value is
NaN and errno is set to EDOM.
atan2
double atan2 ( double y , double x ) ;
Description
This function computes the angle, in the range [ . . ] radians, whose tangent is y/x. In other words, it computes
the angle, in radians, of the vector (x, y) with respect to the +x axis, reckoning the counterclockwise direction as
positive, and returning the value in the range [ . . ].
Return Value
The arc tangent, in radians, of y/x. is returned if x is negative and y is a negative zero, 0.0. is returned, if x is
negative, and y is a positive zero, +0.0.
If either x or y is infinite, atan2 returns, respectively, with the sign of y or zero, and errno is left unchanged.
However, if both arguments are infinite, the return value is NaN and errno is set to EDOM.
A NaN is returned, and errno is set to EDOM, if either x and y are both zero, or if either one of the arguments is a
NaN.
#include
#include
#include
#include
#include
#include
#include
<i o s t r e a m >
<cmath>
<l i s t >
<c a s s e r t >
<string>
<vector>
<a l g o r i t h m >
#define LEFT 1
#define EPS 1 e 10
#define
#define
#define
#define
33
struct Line {
Point p1 , p2 ;
double x , y ;
Line ( ) {}
Line ( CPR p1 , CPR p2 ) : p1 ( p1 ) , p2 ( p2 ) , x ( p2 . x p1 . x ) , y ( p2 . y p1 . y ) {}
bool operator==(CLR l ) {
return ( p1 == l . p1 && p2 == l . p2 ) ;
}
bool operator !=( CLR l ) {
return ! ( t h i s == l ) ;
}
Line operator (CLR l2 ) const {
return Line ( p1 l2 . p1 , p2 l2 . p2 ) ;
}
Line operator+(CLR l2 ) const {
return Line ( p1 + l2 . p1 , p2 + l2 . p2 ) ;
}
friend ostream &operator<<(ostream &output , CLR l ) ;
};
ostream &operator<<(ostream &output , CLR l ) {
output << l . p1 << > << l . p2 ;
return output ;
}
struct Point3D {
double x , y , z ;
Point3D ( ) {}
Point3D ( double x , double y , double z ) : x ( x ) , y ( y ) , z ( z ) {}
Point3D operator (CP3R p2 ) const {
return Point3D ( p2 . x x , p2 . y y , p2 . z z ) ;
}
Point3D operator+(CP3R p2 ) const {
return Point3D ( p2 . x + x , p2 . y + y , p2 . z + z ) ;
}
};
struct Line3D {
Point3D p1 , p2 ;
double x , y , z ;
Line3D ( ) {}
Line3D ( CP3R p1 , CP3R p2 ) : p1 ( p1 ) , p2 ( p2 ) , x ( p2 . x p1 . x ) , y ( p2 . y p1 . y ) , z ( p2 . z
p1 . z ) {}
Line3D operator (CL3R l2 ) const {
return Line3D ( p1 l2 . p1 , p2 l2 . p2 ) ;
}
Line3D operator+(CL3R l2 ) const {
return Line3D ( p1 + l2 . p1 , p2 + l2 . p2 ) ;
34
}
};
struct Polygon {
l i s t <Point> vertices ;
//
v e c t o r <Point> v e r t i c e s ;
//
/
CPR o p e r a t o r [ ] ( i n t i n d e x ) {
return v e r t i c e s [ index ] ;
}
/
friend ostream &operator<<(ostream &output , Polygon &g ) ;
};
ostream &operator<<(ostream &output , Polygon &g ) {
string comma = ;
f o r ( Polygon : : Iterator iter = g . vertices . begin ( ) ; iter != g . vertices . end ( ) ;
++iter ) {
output << comma << iter ;
comma = , ;
}
return output ;
}
Line3D crossProduct ( CL3R l1 , CL3R l2 ) {
return Line3D ( Point3D ( 0 , 0 , 0 ) , Point3D ( l1 . y l2 . z l1 . z l2 . y , l1 . z l2 . x
35
l1 . x l2 . z , l1 . x l2 . y l1 . y l2 . x ) ) ;
}
double zCrossProduct ( CLR l1 , CLR l2 ) {
return l1 . x l2 . y l1 . y l2 . x ;
}
double dotProduct ( CLR l1 , CLR l2 ) {
return l1 . x l2 . x + l1 . y l2 . y ;
}
Line scalarProduct ( CLR l1 , double s ) {
return Line ( s l1 . p1 , s l1 . p2 ) ;
}
12.2
Distances
|P1 P2 |
double pointLineDist ( CPR p , CLR l ) {
Line AP ( l . p1 , p ) ;
return fabs ( zCrossProduct ( AP , l ) ) / length ( l ) ;
}
double pointSegDist ( CPR p , CLR l ) ;
// Return t h e p o s i t i o n o f t h e p o i n t r e l a t i v e t o t h e l i n e .
int relativePos ( CPR p , CLR l ) {
double cz = zCrossProduct ( l , Line ( l . p1 , p ) ) ;
i f ( eq ( cz , 0 . 0 ) )
return ON ;
e l s e i f ( gt ( cz , 0 ) )
return LEFT ;
else
return RIGHT ;
}
//Do we make a l e f t or r i g h t t u r n a t p1 ?
int turnDir ( CPR p0 , CPR p1 , CPR p2 ) {
double z = zCrossProduct ( Line ( p0 , p2 ) , Line ( p0 , p1 ) ) ;
36
i f ( lt ( z , 0 ) )
return LEFT ;
e l s e i f ( gt ( z , 0 ) )
return RIGHT ;
else
return ON ;
}
bool pointOnSeg ( CPR p , CLR l ) {
return ( relativePos ( p , l ) == ON && eq ( length ( l ) , dist ( p , l . p1 ) + dist ( p , l . p2 ) ) ) ;
}
12.3
Intersection
0) )
true ;
t h e same
( relativePos ( l1 . p1 , l2 ) == ON ) ;
}
bool segsIntersect ( CLR l1 , CLR l2 ) {
int r1 = relativePos ( l1 . p1 , l2 ) ;
int r2 = relativePos ( l1 . p2 , l2 ) ;
int r3 = relativePos ( l2 . p1 , l1 ) ;
int r4 = relativePos ( l2 . p2 , l1 ) ;
i f ( r1 == ON | | r2 == ON | | r3 == ON | | r4 == ON )
return true ;
return ( r1 != r2 && r3 != r4 ) ;
}
bool segLineIntersect ( CLR seg , CLR l ) {
int r1 = relativePos ( seg . p1 , l ) ;
int r2 = relativePos ( seg . p2 , l ) ;
return ( r1 r2 <= 0 ) ;
}
12.3.1
For the lines AB and CD in two dimensions, the most straight forward way to calculate the intersection of them is to
solve the system of two equations and two unknowns:
Ax + (Bx Ax )i = Cx + (Dx Cx )j
Ay + (By Ay )i = Cy + (Dy Cy )j
The point of intersection is:
(Ax + (Bx Ax )i, Ay + (By Ay )i)
In three dimensions, solve following system of equations, where i and j are the unknowns:
Ax + (Bx Ax )i = Cx + (Dx Cx )j
Ay + (By Ay )i = Cy + (Dy Cy )j
Az + (Bz Az )i = Cz + (Dz Cz )j
If this system has a solution (i, j), where 0 i 1 and 0 j 1, then the line segments intersect at:
(Ax + (Bx Ax )i, Ay + (By Ay )i, Az + (Bz Az )i)
37
38
12.4
Projection
ab
b
bb
(12.1)
// Return t h e p r o j e c t o f t h e g i v e n p o i n t on t h e g i v e n v e c t o r .
Point project ( CPR p , CLR l ) {
Line AP ( l . p1 , p ) ;
Line vj = scalarProduct ( l , dotProduct ( l , AP ) / length2 ( l ) ) ;
return Point ( vj . p2 vj . p1 + l . p1 ) ;
}
12.5
Reflection
ab
ba
bb
// Return t h e r e f l e c t o f t h e g i v e n p o i n t r e l a t i v e t o t h e g i v e n v e c t o r .
Point reflect ( CPR p , CLR l ) {
Line AP ( l . p1 , p ) ;
Line vj ( l . p1 , project ( p , l ) ) ; // t h e p r o j e c t o f p on l .
Line vr = scalarProduct ( vj , 2 ) ; // t h e r e f l e c t o f p r e l a t i v e t o l .
vr = vr l ;
return Point ( vr . p2 vr . p1 + l . p1 ) ;
}
12.6
Area of polygon
12.7
Transformations
12.7.1
Rotation
39
(12.2)
12.7.2
Line Reflection
1 0
1 0
Reflection matrix relative to the x-axis is
. Reflection matrix relative to the y-axis is
. Reflection
0 1
0 1
0 1
0 1
matrix relative to the line y = x is
. Reflection matrix relative to the line y = x is
. Reflection
1 0
1
0
2
cos 2
sin 2
1m
2m
1
= 1+m
.
matrix relative to the line y = mx is S =
2
sin 2 cos 2
2m
m2 1
12.7.3
Scale
K=
12.7.4
0
k
Perpendicular Projection
1
H = (S + I) =
2
12.7.5
k
0
cos2
sin cos
sin cos
sin2
Amood Monasef
12.8
Point in Triangle
To check if a point A is in a triangle, find another point B which is within the triangle (the average of the three vertices
works well). Then, check if the point A is on the same side of the three lines defined by the edges of the triangle as B.
12.9
struct P0Finder {
bool operator ( ) ( CPR p1 , CPR p2 ) {
i f ( lt ( p1 . y , p2 . y ) )
return true ;
e l s e i f ( eq ( p1 . y , p2 . y ) )
i f ( lt ( p1 . x , p2 . x ) )
return true ;
return f a l s e ;
}
};
struct CVSorter {
Point p0 ;
CVSorter ( CPR p0 ) : p0 ( p0 ) {}
40
41
Chapter 13
Libraries
13.1
STL
=
advance
binary search
count
equal range
find end
for each
inplace merge
lower bound
max size
next permutation
pop
push back
remove
replace
reverse
search
size
stable sort
unique
13.1.1
[]
any
&=
count
adjacent find
begin
copy backward
equal
find
find last
includes
lexicographical compare
max element
mismatch
partition
prev permutation
rbegin
rend
resize
seacrh n
set union
stable partition
transform
<
base
copy
end
fill n
find if
generate n
key comp
max
min element
partial sort copy
pop heap
random shuffle
remove if
replace if
rotate copy
set symmetric difference
splice
top
value comp
|=
flip
^=
none
<<=
reset
>>=
set
~
size
&
test
|
to ulong
<<
>>
string
+=
find
insert
append
find first not of
push back
13.2
atoi
find first of
replace
compare
find last not of
rfind
erase
find last of
substr
Character Classification
isalnum
isxdigit
!
good
!=
back
clear
empty
fill
find first of
generate
iter swap
make pair
min
partial sort
pop front
push heap
remove copy if
replace copy if
rotate
set intersection
sort heap
swap ranges
upper bound
bitset
13.1.2
13.3
==
assign
capacity
count if
erase
find first
front
insert
make heap
merge
nth element
pop back
push front
remove copy
replace copy
reverse copy
set difference
sort
swap
unique copy
isalpha
tolower
iscntrl
toupper
isdigit
isgraph
islower
isprint
clear
read
eof
setstate
fail
width
gcount
write
ispunct
isspace
Streams
>>
ignore
<<
put
bad
rdstate
42
get
getline
isupper
13.3.1
ios-base
adjustfield
flags
noshowpoint
scientific
showpos
13.3.2
app
out
basefield
floatfield
noshowpos
setbase
skipws
boolalpha
hex
noskipws
setf
unitbuf
copyfmt
internal
nouppercase
setiosflags
unsetf
dec
left
oct
setprecision
uppercase
File Streams
ate
putback
binary
readsome
close
seekg
get
tellg
in
trunc
is open
unget
43
open
fill
noboolalpha
resetiosflags
showbase
fixed
noshowbase
right
showpoint