Posts Tagged ‘DP’
All Pair Shortest Path (APSP)
Question : Find shortest paths between all pairs of vertices in a graph.
Floyd-Warshall Algorithm
It is one of the easiest algorithms, and just involves simple dynamic programming. The algorithm can be read from this wikipedia page.
#define SIZE 31 #define INF 1e8 double dis[SIZE][SIZE]; void init(int N) { for (k=0;k<N;k++) for (i=0;i<N;i++) dis[i][j]=INF; } void floyd_warshall(int N) { int i,j,k; for (k=0;k<N;k++) for (i=0;i<N;i++) for (j=0;j<N;j++) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } int main() { //input size N init(N); //set values for dis[i][j] floyd_warshall(N); }
We can also use the algorithm to
- find the shortest path
- we can use another matrix called predecessor matrix to construct the shortest path.
- find negative cycles in a graph.
- If the value of any of the diagonal elements is less than zero after calling the floyd-warshall algorithm then there is a negative cycle in the graph.
- find transitive closure
- to find if there is a path between two vertices we can use a boolean matrix and use and-& and or-| operators in the floyd_warshall algorithm.
- to find the number of paths between any two vertices we can use a similar algorithm.
NJOY!!
-fR0DDY
Longest Common Subsequence (LCS)
The longest common subsequence (LCS) problem is to find the longest subsequence common to all sequences in a set of sequences (often just two).
First we look into only finding the length of LCS. We can easily construct an exponential time recursive algorithm to compute the length of the LCS. But using Dynamic Programming (DP) to compute the solution bottom up the same job can be done in O(mn) time where m and n are the lengths of the subsequences. Here is a C++ code to do so. Note that the code also uses very less space.
int LCS(string X,string Y) { if (Y.length() > X.length()) swap(X,Y); int m = X.length(),n=Y.length(); vector< vector<int> > c(2, vector<int>(n+1,0)); int i,j; for (i=1;i<=m;i++) { for (j=1;j<=n;j++) { if (X[i-1]==Y[j-1]) c[1][j]=c[0][j-1]+1; else c[1][j]=max(c[1][j-1],c[0][j]); } for (j=1;j<=n;j++) c[0][j]=c[1][j]; } return (c[1][n]); }
If we also wish to print the subsequence we use a space of size m x n to get the LCS. Here’s the code
string X,Y; vector< vector<int> > c(101, vector<int>(101,0)); int m,n,ctr; void LCS() { m = X.length(),n=Y.length(); int i,j; for (i=0;i<=m;i++) for (j=0;j<=n;j++) c[i][j]=0; for (i=1;i<=m;i++) for (j=1;j<=n;j++) { if (X[i-1]==Y[j-1]) c[i][j]=c[i-1][j-1]+1; else c[i][j]=max(c[i][j-1],c[i-1][j]); } } void printLCS(int i,int j) { if (i==0 || j==0) return; if (X[i-1]==Y[j-1]) { printLCS(i-1,j-1); cout<<X[i-1]; } else if (c[i][j]==c[i-1][j]) printLCS(i-1,j); else printLCS(i,j-1); } int main() { while(cin>>X>>Y) { LCS(); printLCS(m,n); cout<<endl ; } }
This post is a prequel to posts on similar topics that i wish to write.
NJOY
-fR0D