1.         STRASSENS MATRIX(2*2)

 

#include<stdio.h>

 

int main()

 

{

 

int a[2][2],b[2][2],c[2][2],i,j;

 

int m1,m2,m3,m4,m5,m6,m7;

 

 

 

printf("\nEnter elements of first matrix : ");

 

for(i=0;i<2;i++)

 

{

 

for(j=0;j<2;j++)

 

{

 

scanf("%d",&a[i][j]);

 

}

 

}

 

 

 

printf("\nEnter elements of second matrix : ");

 

for(i=0;i<2;i++)

 

{

 

for(j=0;j<2;j++)

 

{

 

scanf("%d",&b[i][j]);

 

}

 

}

 

 

 

printf("\nFirst Matrix is : \n");

 

for(i=0;i<2;i++)

 

{

 

for(j=0;j<2;j++)

 

{

 

printf("%d\t",a[i][j]);

 

}

 

}

 

 

 

printf("\nSecond Matrix is : \n");

 

for(i=0;i<2;i++)

 

{

 

for(j=0;j<2;j++)

 

{

 

printf("%d\t",b[i][j]);

 

}

 

}

 

 

 

m1 = (a[0][0]+a[1][1]) * (b[0][0]+b[1][1]);

 

m2 = (a[0][1]-a[1][1]) * (b[1][0]+b[1][1]);

 

m3 = (a[0][0]-a[1][0]) * (b[0][0]+b[0][1]);

 

m4 = (a[0][0]+a[0][1]) * (b[1][1]);

 

m5 = (a[1][0]+a[1][1]) * (b[0][0]);

 

m6 = (a[0][0]) * (b[0][1]-b[1][1]);

 

m7 = (a[1][1]) * (b[1][0]-b[0][0]);

 

 

 

c[0][0] = m1+m2-m4+m7;

 

c[0][1] = m4+m6;

 

c[1][0] = m5+m7;

 

c[1][1] = m1-m3-m5+m6;

 

 

 

printf("\nResultant Matrix after strassen multiplication is : \n");

 

for(i=0;i<2;i++)

 

{

 

for(j=0;j<2;j++)

 

{

 

printf("%d\t",c[i][j]);

 

}

 

}

 

return 0;

 

}

 

 

 

2.         STRASSENS MATRIX(N*N)

 

#include <stdio.h>

 

void main()

 

{

 

int i,j,k,m,n,n1,n2,n3,n4,o=0;

 

/*Input first matrix*/

 

printf("\nEnter the order of 1st Matrix:");

 

scanf("%d%d",&n1,&n2);

 

int A[n1][n2];

 

for(i=0;i<n1;i++){

 

printf("Enter the elements of the %d-th row:",i+1);

 

for(j=0;j<n2;j++)

 

scanf(" %d",&A[i][j]);

 

}

 

/*Input second matrix*/

 

printf("\n\nEnter the order of 2nd Matrix:");

 

scanf("%d%d",&n3,&n4);

 

int B[n3][n4];

 

for(i=0;i<n3;i++){

 

printf("Enter the elements of the %d-th row:",i+1);

 

for(j=0;j<n4;j++)

 

scanf(" %d",&B[i][j]);

 

}

 

/*Creating square matrix of order 2^n for all and initializing all elements to 0 except

 

prefixed*/

 

n4=n1>n2?n1:n2;

 

n=n3>n4?n3:n4;

 

while(n>(m=power(2,++o)));

 

int a[m][m],b[m][m],C[m][m];

 

for(i=0;i<m;i++)

 

for(j=0;j<m;j++){

 

a[i][j]=0;

 

b[i][j]=0;

 

}

 

for(i=0;i<n1;i++)

 

for(j=0;j<n2;j++)

 

a[i][j]=A[i][j];

 

for(i=0;i<n2;i++)

 

for(j=0;j<n3;j++)

 

b[i][j]=B[i][j];

 

/*Printing first matrix*/

 

printf("\nThe first matrix is :");

 

for(i=0;i<n1;i++){

 

printf("\n\n\n");

 

for(j=0;j<n2;j++)

 

printf("\t%d",a[i][j]);

 

}

 

/*Printing second matrix*/

 

printf("\n\n\nThe second matrix is :");

 

for(i=0;i<n2;i++){

 

printf("\n\n\n");

 

for(j=0;j<n3;j++)

 

printf("\t%d",b[i][j]);

 

}

 

strassen(a,b,C,m); //Calling the function.

 

/*Printing the final matrix*/

 

printf("\n\n\nThe final matrix is :");

 

for(i=0;i<n1;i++){

 

printf("\n\n\n");

 

for(j=0;j<n3;j++)

 

printf("\t%d",C[i][j]);

 

}

 

}

 

int power(int base, int exp){

 

int i=0, p=1;

 

while(++i<exp+1 && 1*(p*=base));

 

return p;

 

}

 

void add(int* A, int* B, int* C, int n, int x){

 

int i,j, m=x>0?n/2:n;

 

for (i=0;i<m;i++)

 

for (j=0;j<m;j++)

 

*(C+i*m+j) = *(A+i*n+j) + *(B+i*n+j);

 

}

 

void sub(int* A, int* B, int* C, int n, int x){

 

int i,j, m=x>0?n/2:n;

 

for (i=0;i<m;i++)

 

for (j=0;j<m;j++)

 

*(C+i*m+j) = *(A+i*n+j) - *(B+i*n+j);

 

}

 

void strassen(int* A, int* B, int* C, int n){

 

int i,j;

 

if(n==2){

 

int P=(*A+*(A+n+1))*(*B+*(B+n+1)); //P=(A[0][0]+A[1][1])*(B[0][0]+B[1][1])

 

int Q=(*(A+n)+*(A+n+1))*(*B); //Q=(A[1][0]+A[1][1])*B[0][0]

 

int R=(*A)*(*(B+1)-*(B+n+1)); //R=A[0][0]*(B[0][1]-B[1][1])

 

int S=(*(A+n+1))*(*(B+n)-*B); //S=A[1][1]*(B[1][0]-B[0][0])

 

int T=(*A+*(A+1))*(*(B+n+1)); //T=(A[0][0]+A[0][1])*B[1][1]

 

int U=(*(A+n)-*A)*(*B+*(B+1)); //U=(A[1][0]-A[0][0])*(B[0][0]+B[0][1])

 

int V=(*(A+1)-*(A+n+1))*(*(B+n)+*(B+n+1)); //V=(A[0][1]-A[1][1])*(B[1][0]+B[1][1])

 

*         C=P+S-T+V;

 

*(C+1)=R+T;

 

*(C+n)=Q+S;

 

*(C+n+1)=P+R-Q+U;

 

}

 

else{

 

int m=n/2, x[m][m], y[m][m], o[n][n];

 

for(i=0;i<n;i++)

 

for(j=0;j<n;j++)

 

o[i][j]=0;

 

/*P=(A[0][0]+A[1][1])*(B[0][0]+B[1][1])*/

 

int P[m][m];

 

add(A, A+m*(n+1), x, n, 1);

 

add(B, B+m*(n+1), y, n, 1);

 

strassen(x, y, P, m);

 

/*Q=(A[1][0]+A[1][1])*B[0][0]*/

 

int Q[m][m];

 

add(A+m*n, A+m*(n+1), x, n, 1);

 

add(B, o, y, n, 1);

 

strassen(x, y, Q, m);

 

/*R=A[0][0]*(B[0][1]-B[1][1])*/

 

int R[m][m];

 

add(A, o, x, n, 1);

 

sub(B+m, B+m*(n+1), y, n, 1);

 

strassen(x, y, R, m);

 

/*S=A[1][1]*(B[1][0]-B[0][0])*/

 

int S[m][m];

 

add(A+m*(n+1), o, x, n, 1);

 

sub(B+m*n, B, y, n, 1);

 

strassen(x, y, S, m);

 

/*T=(A[0][0]+A[0][1])*B[1][1]*/

 

int T[m][m];

 

add(A, A+m, x, n, 1);

 

add(B+m*(n+1), o, y, n, 1);

 

strassen(x, y, T, m);

 

/*U=(A[1][0]-A[0][0])*(B[0][0]+B[0][1])*/

 

int U[m][m];

 

sub(A+m*n, A, x, n, 1);

 

add(B, B+m, y, n, 1);

 

strassen(x, y, U, m);

 

/*V=(A[0][1]-A[1][1])*(B[1][0]+B[1][1])*/

 

int V[m][m];

 

sub(A+m, A+m*(n+1), x, n, 1);

 

add(B+m*n, B+m*(n+1), y, n, 1);

 

strassen(x, y, V, m);

 

/*Calculating the 4 parts for the result matrix*/

 

int W[m][m], X[m][m], Y[m][m], Z[m][m];

 

sub(V,T,x,m,0);

 

add(S,x,y,m,0);

 

add(P,y,W,m,0); // W=P+S-T+V

 

add(R,T,X,m,0); // X==R+T

 

add(Q,S,Y,m,0); // Y=Q+S

 

sub(U,Q,x,m,0);

 

add(R,x,y,m,0);

 

add(P,y,Z,m,0); // Z=P+R-Q+U

 

/*Conquering 4 parts in the result matrix*/

 

for (i=0;i<m;i++)

 

for (j=0;j<m;j++){

 

*(C+i*n+j) = W[i][j]; //C[0][0]=W

 

*(C+i*n+j+m) = X[i][j]; //C[0][1]=X

 

*(C+(i+m)*n+j) = Y[i][j]; //C[1][0]=Y

 

*(C+(i+m)*n+j+m) = Z[i][j]; //C[1][1]=Z

 

}

 

}

 

}

 

 

 

3. KARATSUBA

 

#include <stdio.h>

 

#include <math.h>

 

 

 

// Get size of the numbers

 

int getSizeOfNumber(long num)

 

{

 

int count = 0;

 

while (num > 0)

 

{

 

count++;

 

num /= 10;

 

}

 

return count;

 

}

 

 

 

long karatsuba(long firstNumber, long secondNumber)

 

{

 

// Base Case

 

if (firstNumber < 10 || secondNumber < 10)

 

return firstNumber * secondNumber;

 

 

 

// determine the size of X and Y

 

int size = fmax(getSizeOfNumber(firstNumber), getSizeOfNumber(secondNumber));

 

 

 

// Split X and Y

 

int n = (int)ceil(size / 2.0);

 

long p = (long)pow(10, n);

 

long a = (long)floor(firstNumber / (double)p);

 

long b = firstNumber % p;

 

long c = (long)floor(secondNumber / (double)p);

 

long d = secondNumber % p;

 

 

 

// Recur until base case

 

long ac = karatsuba(a, c);

 

long bd = karatsuba(b, d);

 

long e = karatsuba(a + b, c + d) - ac - bd;

 

 

 

// return the equation

 

return (long)(pow(10 * 1L, 2 * n) * ac + pow(10 * 1L, n) * e + bd);

 

}

 

 

 

int main()

 

{

 

long int num1,num2;

 

printf("karatsuba's Fast multiplication execution : \n ");

 

printf("Enter the first number : ");

 

scanf("%ld",&num1);

 

printf("Enter the second number : ");

 

scanf("%ld",&num2);

 

printf("The result of multiplication : %ld",karatsuba(num1,num2));

 

 

 

return 0;

 

}

 

 

 

 

 

 

 

4. GRAPH COLORING

 

#include<stdio.h>

 

int G[10][10],m,edges,color_tab[10],v1,v2,i,j,n,a,b;

 

void Gen_Col_Value(int,int);

 

void Gr_coloring(int,int);

 

int main()

 

{

 

printf("\nEnter the number of nodes & edges\n");

 

scanf("%d%d",&n,&edges);

 

m=n-1;

 

printf("\nEnter the edges of the graph\n\n");

 

for (i=1;i<=edges; i++)

 

{

 

printf("Enter value of x,y\n");

 

scanf("%d%d",&v1,&v2);

 

G[v1][v2] = G[v2][v1] = 1;

 

printf("\n");

 

}

 

Gr_coloring(1,n);

 

printf("\n The Vertices To be Colored As...\n");

 

for(i=1;i<=n;i++)

 

printf("\n V%d:=%d",i,color_tab[i]);

 

return 0;

 

}

 

void Gen_Col_Value(int k,int n)

 

{

 

while(1)

 

{

 

a=color_tab[k]+1;

 

b=m+1;

 

color_tab[k] = a%b;

 

if(color_tab[k]==0) return;

 

for(j=1;j<=n;j++)

 

{

 

if(G[k][j] && color_tab[k]==color_tab[j])

 

break;

 

}

 

if(j==n+1) return;

 

}

 

}

 

void Gr_coloring(int k,int n)

 

{

 

Gen_Col_Value(k,n);

 

if(color_tab[k]==0) return;

 

if(k==n)  return;

 

else Gr_coloring(k+1,n);

 

}

 

 

 

5. JOB SEQUENCING

 

//write a c program to implement  job sequencing with deadline take input from user

 

 

 

#include<stdio.h>

 

#define MAX 100

 

 

 

int main()

 

{

 

int n,i;

 

int Deadline[MAX], Profit[MAX];

 

 

 

printf("Enter the number of jobs: ");

 

scanf("%d", &n);

 

 

 

printf("\nEnter the deadlines and profits of each job:\n");

 

for (i = 0; i < n; i++)

 

{

 

printf("Job %d: ", i+1);

 

scanf("%d %d", &Deadline[i], &Profit[i]);

 

}

 

 

 

int maxProfit = 0;

 

int maxDeadline = 0;

 

 

 

for (i = 0; i < n; i++)

 

{

 

if (Deadline[i] > maxDeadline)

 

maxDeadline = Deadline[i];

 

}

 

 

 

int slot[maxDeadline];

 

 

 

for (i = 0; i < maxDeadline; i++)

 

slot[i] = -1;

 

 

 

for (i = 0; i < n; i++)

 

{

 

int j = Deadline[i] - 1;

 

while (j >= 0)

 

{

 

if (slot[j] == -1)

 

{

 

slot[j] = i;

 

maxProfit += Profit[i];

 

break;

 

}

 

j--;

 

}

 

}

 

 

 

printf("\nThe maximum profit is: %d\n", maxProfit);

 

printf("\nThe sequence of jobs are: ");

 

for (i = 0; i < maxDeadline; i++)

 

{

 

if (slot[i] != -1)

 

printf("%d ", slot[i]+1);

 

}

 

printf("\n");

 

 

 

return 0;

 

}

 

 

 

6. Matrix Chain Multiplication

 

#include<stdio.h>

 

#include<limits.h>

 

// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n

 

int MatrixChainMultiplication(int p[], int n)

 

{

 

int m[n][n];

 

int i, j, k, L, q;

 

for (i=1; i<n; i++)

 

m[i][i] = 0; //number of multiplications are 0(zero) when there is only

 

one matrix

 

//Here L is chain length. It varies from length 2 to length n.

 

for (L=2; L<n; L++)

 

{

 

for (i=1; i<n-L+1; i++)

 

{

 

j = i+L-1;

 

m[i][j] = INT_MAX; //assigning to maximum value

 

for (k=i; k<=j-1; k++)

 

{

 

q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];

 

if (q < m[i][j])

 

{

 

m[i][j] = q; //if number of multiplications found less that number

 

will be updated.

 

}

 

}

 

}

 

}

 

return m[1][n-1]; //returning the final answer which is M[1][n]

 

}

 

int main()

 

{

 

int n,i;

 

printf("Enter number of matrices\n");

 

scanf("%d",&n);

 

n++;

 

int arr[n];

 

printf("Enter dimensions \n");

 

for(i=0;i<n;i++)

 

{

 

printf("Enter d%d : ",i);

 

scanf("%d",&arr[i]);

 

}

 

int size = sizeof(arr)/sizeof(arr[0]);

 

printf("Minimum number of multiplications is %d ",

 

MatrixChainMultiplication(arr, size));

 

return 0;

 

}

 

 

 

7. longest common subsequence

 

#include <stdio.h>

 

#include <string.h>

 

int i, j, m, n, LCS_table[20][20];

 

char S1[20] = "ACGTTCGA", S2[20] = "BCTBBCA", b[20][20];

 

void lcsAlgo() {

 

m = strlen(S1);

 

n = strlen(S2);

 

// Filling 0's in the matrix

 

for (i = 0; i <= m; i++)

 

LCS_table[i][0] = 0;

 

for (i = 0; i <= n; i++)

 

LCS_table[0][i] = 0;

 

// Building the mtrix in bottom-up way

 

for (i = 1; i <= m; i++)

 

for (j = 1; j <= n; j++) {

 

if (S1[i - 1] == S2[j - 1]) {

 

LCS_table[i][j] = LCS_table[i - 1][j - 1] + 1;

 

} else if (LCS_table[i - 1][j] >= LCS_table[i][j - 1]) {

 

LCS_table[i][j] = LCS_table[i - 1][j];

 

} else {

 

LCS_table[i][j] = LCS_table[i][j - 1];

 

}

 

}

 

int index = LCS_table[m][n];

 

char lcsAlgo[index + 1];

 

lcsAlgo[index] = '\0';

 

int i = m, j = n;

 

while (i > 0 && j > 0) {

 

if (S1[i - 1] == S2[j - 1]) {

 

lcsAlgo[index - 1] = S1[i - 1];

 

i--;

 

j--;

 

index--;

 

}

 

else if (LCS_table[i - 1][j] > LCS_table[i][j - 1])

 

i--;

 

else

 

j--;

 

}

 

// Printing the sub sequences

 

printf("S1 : %s \nS2 : %s \n", S1, S2);

 

printf("LCS: %s", lcsAlgo);

 

}

 

int main() {

 

printf("Name : Harsha Dulhani\n");

 

printf("Register NO : 22MCB0012\n");

 

lcsAlgo();

 

printf("\n");

 

}

 

8. N-QUEENS PROBLEM

 

#include <stdio.h>

 

#include <stdbool.h>

 

int board[10][10], n;

 

 

 

/*A utility function to check if a queen can be placed on board[row][col]*/

 

bool isSafe(int row, int col){

 

int i, j;

 

for(i=0; i<col; i++)

 

if(board[row][i])

 

return false;

 

 

 

for(i=row, j=col; i>=0 && j>=0; i--, j--)

 

if(board[i][j])

 

return false;

 

 

 

for(i=row, j=col; j>=0 && i<n; i++, j--)

 

if(board[i][j])

 

return false;

 

 

 

return true;

 

}

 

 

 

/* A recursive utility function to solve N Queen problem */

 

bool solveNQUtil(int col){

 

if(col == n){

 

return true;

 

}

 

int i;

 

for(i=0; i<n; i++){

 

if(isSafe(i, col)){

 

board[i][col] = 1;

 

if(solveNQUtil(col+1))

 

return true;

 

board[i][col] = 0;

 

}

 

}

 

return false;

 

}

 

 

 

/* This function solves the N Queen problem using Backtracking. It mainly uses solveNQUtil() to solve the problem. It returns false if queens cannot be placed, otherwise return true and prints placement of queens in the form of 1s. Please note that there may be more than one solutions, this function prints one  of the feasible solutions.*/

 

bool solveNQ(){

 

if(solveNQUtil(0) == false){

 

printf("Solution does not exist");

 

return false;

 

}

 

 

 

int i, j;

 

printf("\nSolution:\n");

 

for(i=0; i<n; i++){

 

for(j=0; j<n; j++){

 

printf("%d\t", board[i][j]);

 

}

 

printf("\n");

 

}

 

return true;

 

}

 

 

 

int main(){

 

printf("\nEnter the number of Queens: ");

 

scanf("%d", &n);

 

solveNQ();

 

return 0;

 

}

 

 

 

 

 

9. SUM OF SUBSET

 

#include <stdio.h>

 

#include <stdlib.h>

 

 

 

int x[20],w[20],d,count=0;

 

 

 

void subset(int cs,int k,int r)

 

{

 

int i;

 

x[k]=1;

 

if(cs+w[k]==d)

 

{

 

printf("\nSubset %d\n",++count);

 

for(i=0;i<=k;i++)

 

if(x[i]==1)

 

printf("%d\t",w[i]);

 

}

 

else if(cs+w[k]+w[k+1]<=d)

 

subset(cs+w[k],k+1,r-w[k]);

 

if((cs+r-w[k]>=d)&&(cs+w[k+1]<=d))

 

{

 

x[k]=0;

 

subset(cs,k+1,r-w[k]);

 

}

 

}

 

 

 

int main()

 

{

 

int i,n,sum=0;

 

printf("Enter the no. of elements:");

 

scanf("%d",&n);

 

printf("\nEnter the elements in ascending order:\n");

 

for(i=0;i<n;i++)

 

{

 

scanf("%d",&w[i]);

 

sum+=w[i];

 

}

 

printf("\nEnter the sum value to obtain:");

 

scanf("%d",&d);

 

if(sum<d)

 

{

 

printf("No subset possible");

 

exit(0);

 

}

 

subset(0,0,sum);

 

if(count==0)

 

printf("\nNo subset possible");

 

return 0;

 

}

 

 

 

10. FORD FULKERSON

 

#include <stdio.h>

 

#define A 0

 

#define B 1

 

#define C 2

 

#define MAX_NODES 1000

 

#define O 1000000000

 

 

 

int n;

 

int e;

 

int capacity[MAX_NODES][MAX_NODES];

 

int flow[MAX_NODES][MAX_NODES];

 

int color[MAX_NODES];

 

int pred[MAX_NODES];

 

 

 

int min(int x, int y) {

 

return x < y ? x : y;

 

}

 

 

 

int head, tail;

 

int q[MAX_NODES + 2];

 

 

 

void enqueue(int x) {

 

q[tail] = x;

 

tail++;

 

color[x] = B;

 

}

 

 

 

int dequeue() {

 

int x = q[head];

 

head++;

 

color[x] = C;

 

return x;

 

}

 

 

 

// Using BFS as a searching algorithm

 

int bfs(int start, int target) {

 

int u, v;

 

for (u = 0; u < n; u++) {

 

color[u] = A;

 

}

 

head = tail = 0;

 

enqueue(start);

 

pred[start] = -1;

 

while (head != tail) {

 

u = dequeue();

 

for (v = 0; v < n; v++) {

 

if (color[v] == A && capacity[u][v] - flow[u][v] > 0) {

 

enqueue(v);

 

pred[v] = u;

 

}

 

}

 

}

 

return color[target] == C;

 

}

 

 

 

// Applying fordfulkerson algorithm

 

int fordFulkerson(int source, int sink) {

 

int i, j, u;

 

int max_flow = 0;

 

for (i = 0; i < n; i++) {

 

for (j = 0; j < n; j++) {

 

flow[i][j] = 0;

 

}

 

}

 

 

 

// Updating the residual values of edges

 

while (bfs(source, sink)) {

 

int increment = O;

 

for (u = n - 1; pred[u] >= 0; u = pred[u]) {

 

increment = min(increment, capacity[pred[u]][u] - flow[pred[u]][u]);

 

}

 

for (u = n - 1; pred[u] >= 0; u = pred[u]) {

 

flow[pred[u]][u] += increment;

 

flow[u][pred[u]] -= increment;

 

}

 

// Adding the path flows

 

max_flow += increment;

 

}

 

return max_flow;

 

}

 

 

 

int main() {

 

for (int i = 0; i < n; i++) {

 

for (int j = 0; j < n; j++) {

 

capacity[i][j] = 0;

 

}

 

}

 

n = 6;

 

e = 7;

 

 

 

capacity[0][1] = 8;

 

capacity[0][4] = 3;

 

capacity[1][2] = 9;

 

capacity[2][4] = 7;

 

capacity[2][5] = 2;

 

capacity[3][5] = 5;

 

capacity[4][2] = 7;

 

capacity[4][3] = 4;

 

 

 

int s = 0, t = 5;

 

printf("Max Flow: %d\n", fordFulkerson(s, t));

 

}

 

 

 

 

 

11. EDMOND KARP

 

#include<cstdio>

 

#include<cstdio>

 

#include<queue>

 

#include<cstring>

 

#include<vector>

 

#include<iostream>

 

#include<conio.h>

 

using namespace std;

 

int capacities[10][10];

 

int flowPassed[10][10];

 

vector<int> graph[10];

 

int parentsList[10];

 

int currentPathCapacity[10];

 

 

 

int bfs(int startNode, int endNode)

 

{

 

memset(parentsList, -1, sizeof(parentsList));

 

memset(currentPathCapacity, 0, sizeof(currentPathCapacity));

 

queue<int> q;

 

q.push(startNode);

 

parentsList[startNode] = -2;

 

currentPathCapacity[startNode] = 999;

 

while(!q.empty())

 

{

 

int currentNode = q.front();

 

q.pop();

 

for(int i=0; i<graph[currentNode].size(); i++)

 

{

 

int to = graph[currentNode][i];

 

 

 

if(parentsList[to] == -1)

 

{

 

if(capacities[currentNode][to] - flowPassed[currentNode][to] > 0)

 

{

 

parentsList[to] = currentNode;

 

currentPathCapacity[to] = min(currentPathCapacity[currentNode],

 

capacities[currentNode][to] - flowPassed[currentNode][to]);

 

if(to == endNode)

 

{

 

return currentPathCapacity[endNode];

 

}

 

q.push(to);

 

}

 

}

 

}

 

}

 

return 0;

 

}

 

int edmondsKarp(int startNode, int endNode)

 

{

 

int maxFlow = 0;

 

while(true)

 

{

 

int flow = bfs(startNode, endNode);

 

if (flow == 0)

 

{

 

break;

 

}

 

maxFlow += flow;

 

int currentNode = endNode;

 

 

 

while(currentNode != startNode)

 

{

 

int previousNode = parentsList[currentNode];

 

flowPassed[previousNode][currentNode] += flow;

 

flowPassed[currentNode][previousNode] -= flow;

 

currentNode = previousNode;

 

}

 

}

 

return maxFlow;

 

}

 

int main(){

 

int nodesCount, edgesCount;

 

cout<<"enter the number of nodes and edges\n";

 

cin>>nodesCount>>edgesCount;

 

int source, sink;

 

cout<<"enter the source and sink\n";

 

cin>>source>>sink;

 

for(int edge = 0; edge < edgesCount; edge++)

 

{

 

cout<<"enter the start and end vertex alongwith capacity\n";

 

int from, to, capacity;

 

cin>>from>>to>>capacity;

 

capacities[from][to] = capacity;

 

graph[from].push_back(to);

 

graph[to].push_back(from);

 

}

 

int maxFlow = edmondsKarp(source, sink);

 

cout<<endl<<endl<<"Max Flow is:"<<maxFlow<<endl;

 

}

 

 

 

 

 

12. PUSH RELABEL

 

#include <bits/stdc++.h>

 

using namespace std;

 

 

 

struct Edge

 

{

 

int flow;

 

int capacity;

 

int u, v;

 

 

 

Edge(int flow, int capacity, int u, int v)

 

{

 

this->flow = flow;

 

this->capacity = capacity;

 

this->u = u;

 

this->v = v;

 

}

 

};

 

 

 

struct Vertex

 

{

 

int height, e_flow;

 

 

 

Vertex(int height, int e_flow)

 

{

 

this->height = height;

 

this->e_flow = e_flow;

 

}

 

};

 

 

 

// To represent a flow network

 

class Graph

 

{

 

int V;

 

vector<Vertex> vertex;

 

vector<Edge> edge;

 

bool push(int u);

 

void relabel(int u);

 

void preflow(int source);

 

void ReverseEdgeFlowUpdate(int i, int flow);

 

 

 

public:

 

Graph(int V);

 

void addEdge(int u, int v, int w);

 

int getMaximumFlow(int source, int sink);

 

};

 

 

 

Graph::Graph(int V)

 

{

 

this->V = V;

 

for (int i = 0; i < V; i++)

 

vertex.push_back(Vertex(0, 0));

 

}

 

 

 

// To push flow from overflowing Vertex u

 

bool Graph::push(int u)

 

{

 

for (int i=0; i <edge.size(); i++)

 

{

 

if (edge[i].u == u)

 

{

 

if (edge[i].flow == edge[i].capacity)

 

continue;

 

if (vertex[u].height > vertex[edge[i].v].height)

 

{

 

int flow = min(edge[i].capacity - edge[i].flow,

 

vertex[u].e_flow);

 

 

 

vertex[u].e_flow = vertex[u].e_flow-flow;

 

vertex[edge[i].v].e_flow = vertex[edge[i].v].e_flow + flow;

 

edge[i].flow = edge[i].flow + flow;

 

 

 

ReverseEdgeFlowUpdate(i, flow);

 

 

 

return true;

 

}

 

}

 

}

 

return false;

 

}

 

 

 

// function to Relabel vertex u

 

void Graph::relabel(int u)

 

{

 

int maximum_height = INT_MAX;

 

int n=edge.size();

 

// To Find the adjacent with minimum height

 

for (int i = 0; i < n; i++)

 

{

 

if (edge[i].u == u)

 

{

 

if (edge[i].flow == edge[i].capacity)

 

continue;

 

 

 

// for Updating the minimum height

 

if (vertex[edge[i].v].height < maximum_height)

 

{

 

maximum_height = vertex[edge[i].v].height;

 

// updating the height of u

 

vertex[u].height = maximum_height + 1;

 

}

 

}

 

}

 

}

 

 

 

void Graph::preflow(int source)

 

{

 

vertex[source].height = vertex.size();

 

int n=edge.size();

 

for (int i = 0; i < n; i++)

 

{

 

if (edge[i].u == source)

 

{

 

edge[i].flow = edge[i].capacity;

 

 

 

// Initialize excess flow for adjacent v

 

vertex[edge[i].v].e_flow = vertex[edge[i].v].e_flow + edge[i].flow;

 

edge.push_back(Edge(-edge[i].flow, 0, edge[i].v, source));

 

}

 

}

 

}

 

 

 

void Graph::addEdge(int u, int v, int capacity)

 

{

 

edge.push_back(Edge(0, capacity, u, v));

 

}

 

 

 

// To Update reverse flow for flow added on ith Edge

 

void Graph::ReverseEdgeFlowUpdate(int i, int flow)

 

{

 

int u = edge[i].v;

 

int v = edge[i].u;

 

int j=0, n=edge.size();

 

 

 

while (j < n)

 

{

 

if (edge[j].v == v && edge[j].u == u)

 

{

 

edge[j].flow -= flow;

 

return;

 

}

 

j++;

 

}

 

 

 

// adding the reverse Edge in the residual graph

 

Edge e = Edge(0, flow, u, v);

 

edge.push_back(e);

 

}

 

 

 

//Function to return an index of overflowing Vertex

 

int overFlowVertex(vector<Vertex>& vertex)

 

{

 

int n=vertex.size();

 

for (int i = 1; i < n - 1; i++)

 

if (vertex[i].e_flow > 0)

 

return i;

 

return -1;

 

}

 

 

 

// The main function is to print the maximum flow of the graph

 

int Graph::getMaximumFlow(int source, int sink)

 

{

 

preflow(source);

 

while (overFlowVertex(vertex) != -1)

 

{

 

int u = overFlowVertex(vertex);

 

if (!push(u))

 

relabel(u);

 

}

 

return vertex.back().e_flow;

 

}

 

 

 

 

 

// Driver Code

 

int main()

 

{

 

int V;

 

cout << "\nEnter the number of vertices : ";

 

cin >> V;

 

Graph g(V);

 

int E;

 

cout << "\nEnter the number of edges : ";

 

cin >> E;

 

int a,b,c;

 

cout << "\nEnter edges like.....vertex1[space]vertex2[space]weight :";

 

for (int i = 0; i < E; ++i) {

 

cin >> a >> b >> c;

 

g.addEdge(a,b,c);

 

}

 

int source;

 

int sink;

 

cout << "\nEnter source and destination : ";

 

cin >> source >> sink;

 

 

 

cout << "\nMaximum flow is " << g.getMaximumFlow(source, sink);

 

return 0;

 

}

 

 

 

13. RELABEL TO FRONT

 

14. CYCLE CANCELLATION

 

#include <iostream>

 

#include <list>

 

#include <algorithm>

 

#include <vector>

 

#include <iomanip>

 

#include <string>

 

#include <sstream>

 

#include <queue>

 

#define int_max 100000

 

using namespace std;

 

// An edge is represented as a struct

 

// Fields:

 

// destination - denotes the ending node of an edge. For example, 'v' in u--

 

>v

 

// capacity - the maximum capacity of an edge

 

// residualFlow - the residual amount of flow that can flow through the edge

 

// counterEdge - a pointer to the counter edge in residual graph for

 

performance optimization

 

struct Edge{

 

int destination;

 

int capacity;

 

int residualFlow;

 

int cost;

 

Edge* counterEdge;

 

};

 

// A graph is represented as a struct

 

// Fields:

 

// numVertices - denotes the number of vertices in the graph

 

// adj - Adjacency list : Collection of unordered lists one for each vertex

 

struct Graph{

 

int numVertices;

 

vector<Edge*> *adj;

 

};

 

Graph g;

 

Graph resGraph;

 

// Generates a new edge (allocating space dynamically) and returns a pointed to

 

the edge

 

Edge* genEdge(int destination, int capacity, int residualFlow, int cost){

 

Edge* e1 = new Edge;

 

e1->destination = destination;

 

e1->capacity = capacity;

 

e1->residualFlow = residualFlow;

 

e1->cost = cost;

 

return e1;

 

}

 

// Prints all the edges in the graph

 

// Output:

 

// List of edges where each edge is represented by

 

// u(start node) v(end node) flow capacity

 

int printGraph(Graph g){

 

for(int i=0; i<g.numVertices; i++){

 

for(int j=0; j<g.adj[i].size(); j++){

 

cout << i+1 << " " << g.adj[i][j]->destination+1 << " " << (g.adj[i][j]-

 

>capacity - g.adj[i][j]->residualFlow) << " " << g.adj[i][j]->cost << endl;

 

}

 

}

 

return 0;

 

}

 

void printParams(int parentVertex[], int distance[]){

 

cout << "Parents Vertex:\n";

 

for(int i=0; i<g.numVertices; i++){

 

cout << parentVertex[i] << " ";

 

}

 

cout << endl;

 

cout << "Distance Vertex:\n";

 

for(int i=0; i<g.numVertices; i++){

 

cout << distance[i] << " ";

 

}

 

cout << endl;

 

}

 

// Detects the presence of negative cycles in graph

 

// Output:

 

// -1 if no negative cycles present

 

// node_num index of a node in negative cycle

 

// Lists parentVertex and parentEdge are updated and can be used to reconstruct

 

the negative cycle

 

int BFCycleDetection(Graph resGraph, int source, int parentVertex[], Edge*

 

parentEdge[]){

 

// Initialize variables that will be needed

 

int cycle_node = -1;

 

int numVertices = resGraph.numVertices;

 

vector<Edge*> *adj = resGraph.adj;

 

int distance[numVertices];

 

// Initialize visited, parentVertex and distance

 

for(int i=0; i<numVertices; i++){

 

parentVertex[i] = -1;

 

distance[i] = INT_MAX;

 

}

 

// BF - Relax edges repeatedly

 

distance[source] = 0;

 

for(int i=0; i<numVertices-1; i++){

 

// loop on all edges

 

for(int u=0; u<numVertices; u++){

 

for(int e=0; e<adj[u].size(); e++){

 

if(adj[u][e]->residualFlow > 0){

 

int v = adj[u][e]->destination;

 

int w = adj[u][e]->cost;

 

if(distance[v]>distance[u]+w){

 

distance[v] = distance[u]+w;

 

parentVertex[v] = u;

 

parentEdge[v] = adj[u][e];

 

}

 

}

 

}

 

}

 

}

 

// Check for negative weight cycle - loop on all edges

 

for(int u=0; u<numVertices; u++){

 

for(int e=0; e<adj[u].size(); e++){

 

if(adj[u][e]->residualFlow > 0){

 

int v = adj[u][e]->destination;

 

int w = adj[u][e]->cost;

 

if(distance[v]>distance[u]+w){

 

return v; // Negative cycle detected!

 

}

 

}

 

}

 

}

 

return cycle_node;

 

}

 

// Cancels all negative cycles

 

// Output:

 

// costSaved amount of cost saved by cycle detection and cancellation

 

int cancelNegativeCycles(Graph resGraph){

 

int costSaved=0, cyclePossible=1, u, v;

 

Edge *te1, *te2;

 

int numVertices = resGraph.numVertices;

 

while(cyclePossible){

 

cyclePossible=0;

 

for(int i=0; i<numVertices; i++){

 

int parent[g.numVertices];

 

Edge* parentEdge[g.numVertices];

 

int node_num = BFCycleDetection(resGraph, i, parent, parentEdge);

 

if(node_num!=-1){ // A cycle is detected

 

cyclePossible=1;

 

// Calculate path flow

 

int path_flow = INT_MAX;

 

v=node_num; u = parent[v]; te1 = parentEdge[v];

 

path_flow = min(path_flow, te1->residualFlow);

 

for (v=u; v!=node_num; v=parent[v]){

 

u = parent[v];

 

te1 = parentEdge[v];

 

path_flow = min(path_flow, te1->residualFlow);

 

}

 

// Update graph by removing the cycle

 

v=node_num; u = parent[v];

 

te1 = parentEdge[v];

 

te2 = te1->counterEdge;

 

te1->residualFlow -= path_flow;

 

te2->residualFlow += path_flow;

 

costSaved += path_flow*(te1->cost);

 

for (v=u; v != node_num; v=parent[v]){

 

u = parent[v];

 

te1 = parentEdge[v];

 

te2 = te1->counterEdge;

 

te1->residualFlow -= path_flow;

 

te2->residualFlow += path_flow;

 

costSaved += path_flow*(te1->cost);

 

}

 

}

 

}

 

}

 

return -1*costSaved;

 

}

 

// Finds the shortest path from source to sink

 

// Output:

 

// 0 if no path exists from source to sink

 

// 1 if there is a path from source to sink

 

// Lists parentVertex and parentEdge are updated and can be used to reconstruct

 

the shortest path

 

bool BF(Graph resGraph, int source, int sink, int parentVertex[], Edge*

 

parentEdge[]){

 

// Initialize variables that will be needed

 

int numVertices = resGraph.numVertices;

 

vector<Edge*> *adj = resGraph.adj;

 

int distance[numVertices];

 

// Initialize visited, parentVertex and distance

 

for(int i=0; i<numVertices; i++){

 

parentVertex[i] = -1;

 

distance[i] = INT_MAX;

 

}

 

// printParams(parentVertex, distance);

 

// BF

 

distance[source] = 0;

 

for(int i=0; i<numVertices-1; i++){

 

// loop on all edges

 

for(int u=0; u<numVertices; u++){

 

for(int e=0; e<adj[u].size(); e++){

 

if(adj[u][e]->residualFlow > 0){

 

int v = adj[u][e]->destination;

 

int w = adj[u][e]->cost;

 

if(distance[v]>distance[u]+w){

 

distance[v] = distance[u]+w;

 

parentVertex[v] = u;

 

parentEdge[v] = adj[u][e];

 

}

 

}

 

}

 

}

 

// printParams(parentVertex, distance);

 

}

 

if(parentVertex[sink] == -1){

 

return false;

 

}else{

 

return true;

 

}

 

}

 

// Calculates the cost of flow 'requiredFlow' from 's' to 't'

 

// Returns 'INT_MAX' if such a flow is not possible

 

int calcMinCostFlow(int s, int t, int requiredFlow){

 

int u, v, currFlow=0, runningCost=0;

 

Edge *te1, *te2;

 

// Detect negative cycles and remove

 

int benifit = cancelNegativeCycles(resGraph);

 

if(benifit){

 

cout << "Negative cycle detected and removed. Resulting cost benifit is "

 

<< benifit << endl;

 

}

 

// Run shortest path augmentation

 

int parent[g.numVertices];

 

Edge* parentEdge[g.numVertices];

 

while (BF(resGraph, s, t, parent, parentEdge)){

 

int path_flow = INT_MAX;

 

for (v=t; v!=s; v=parent[v]){

 

u = parent[v];

 

te1 = parentEdge[v];

 

path_flow = min(path_flow, te1->residualFlow);

 

}

 

path_flow = min(path_flow, requiredFlow-currFlow);

 

for (v=t; v != s; v=parent[v]){

 

u = parent[v];

 

te1 = parentEdge[v];

 

te2 = te1->counterEdge;

 

te1->residualFlow -= path_flow;

 

te2->residualFlow += path_flow;

 

runningCost += path_flow*(te1->cost);

 

}

 

currFlow += path_flow;

 

if(currFlow == requiredFlow){

 

break;

 

}

 

}

 

if(currFlow == requiredFlow){

 

return runningCost;

 

}else{

 

return INT_MAX;

 

}

 

}

 

int main(){

 

cout<<"******Name : Harsha Dulhani******"<<endl;

 

cout<<"******Register No : 22MCB0012******"<<endl;

 

int numVertices, numEdges, source, destination, flow;

 

int tu, tv, tcap, tcost, tflow;

 

// Scan the graph and question configurations

 

cout<<"Enter No of Vertices, No .of Edges, Possible Flow, Source,

 

Destination respectively"<<endl;

 

cin >> numVertices >> numEdges;

 

cin >> flow;

 

cin >> source >> destination;

 

source--; destination--; // as indexing starts from 0

 

// Initialize the graphs

 

g.numVertices = numVertices;

 

g.adj = new vector<Edge*>[numVertices];

 

resGraph.numVertices = numVertices;

 

resGraph.adj = new vector<Edge*>[numVertices];

 

cout<<"Edge data"<<endl;

 

cout<<"Enter u, v, Capacity, Cost, Edge_flow respectively"<<endl;

 

// Input graph parameters

 

for(int i=0; i<numEdges; i++){

 

cin >> tu >> tv >> tcap >> tcost >> tflow;

 

cout<<"Edge from "<<tu <<" to "<<tv<<" Data completed"<<endl<<endl;

 

tu--; tv--; // as indexing starts from 0

 

// Add edge to graph and edge and counter-edge to residual graph

 

Edge* tmpEdge1 = genEdge(tv, tcap, tcap-tflow, tcost);

 

Edge* tmpEdge2 = genEdge(tu, tcap, tflow, -1*tcost);

 

tmpEdge1->counterEdge = tmpEdge2;

 

tmpEdge2->counterEdge = tmpEdge1;

 

g.adj[tu].push_back(tmpEdge1);

 

resGraph.adj[tu].push_back(tmpEdge1);

 

resGraph.adj[tv].push_back(tmpEdge2);

 

}

 

// Print initial state of graph

 

cout << "Initial Graph:\n";

 

printGraph(g);

 

//cout << "hello\n";

 

// Run min-cost flow algorithm

 

int mincost = calcMinCostFlow(source, destination, flow);

 

// Print final state of graph

 

if(mincost == INT_MAX){

 

// cout << "The given flow is not possible!\n";

 

}else{

 

cout << "The minimum cost for the additional flow is " << mincost <<

 

endl;

 

cout << "Final Graph:\n";

 

printGraph(g);

 

}

 

return 0;

 

}

 

Naive string matching

#include <stdio.h>

#include <string.h>

 

int naive_string_match(char text[], char pattern[]) {

int text_len = strlen(text);

int pattern_len = strlen(pattern);

 

for (int i = 0; i <= text_len - pattern_len; i++) {

int j;

for (j = 0; j < pattern_len; j++) {

if (text[i + j] != pattern[j]) {

break;

}

}

if (j == pattern_len) {

return i;

}

}

return -1;

}

 

int main() {

char text[] = "abcdeabcdeabcde";

char pattern[] = "abcde";

int position = naive_string_match(text, pattern);

if (position != -1) {

printf("Pattern found at position %d\n", position);

} else {

printf("Pattern not found\n");

}

return 0;

}

 

kmp string matching

#include <stdio.h>

#include <string.h>

 

void compute_lps(char pattern[], int m, int lps[]) {

int len = 0;

lps[0] = 0;

 

int i = 1;

while (i < m) {

if (pattern[i] == pattern[len]) {

len++;

lps[i] = len;

i++;

} else {

if (len != 0) {

len = lps[len - 1];

} else {

lps[i] = 0;

i++;

}

}

}

}

 

int kmp_string_match(char text[], char pattern[]) {

int n = strlen(text);

int m = strlen(pattern);

 

int lps[m];

compute_lps(pattern, m, lps);

 

int i = 0, j = 0;

while (i < n) {

if (pattern[j] == text[i]) {

i++;

j++;

}

if (j == m) {

return i - j;

} else if (i < n && pattern[j] != text[i]) {

if (j != 0) {

j = lps[j - 1];

} else {

i = i + 1;

}

}

}

return -1;

}

 

int main() {

char text[] = "abcdeabcdeabcde";

char pattern[] = "abcde";

int position = kmp_string_match(text, pattern);

if (position != -1) {

printf("Pattern found at position %d\n", position);

} else {

printf("Pattern not found\n");

}

return 0;

}

 

rabin KARP

 

#include <stdio.h>

#include <string.h>

#include <math.h>

 

#define d 256

 

void rabin_karp(char text[], char pattern[], int q) {

int n = strlen(text);

int m = strlen(pattern);

int p = 0;

int t = 0;

int h = 1;

int j;

int flag = 0;

 

for (int i = 0; i < m - 1; i++) {

h = (h * d) % q;

}

 

for (int i = 0; i < m; i++) {

p = (d * p + pattern[i]) % q;

t = (d * t + text[i]) % q;

}

 

for (int i = 0; i <= n - m; i++) {

if (p == t) {

for (j = 0; j < m; j++) {

if (text[i + j] != pattern[j]) {

break;

}

}

 

if (j == m) {

flag = 1;

printf("Pattern found at index %d\n", i);

}

}

 

if (i < n - m) {

t = (d * (t - text[i] * h) + text[i + m]) % q;

if (t < 0) {

t = t + q;

}

}

}

if(!flag)

printf("Pattern not found\n");

}

 

int main() {

char text[] = "abcdeabcdeabcde";

char pattern[] = "abcde";

int q = 101;

rabin_karp(text, pattern, q);

return 0;

}