All notes are from internet and they are only for my personally quick revision.
Necessary algorithms for Google Interview
1.binary tree
2. graph study notes
3.Dijkstra Algorithm
/*
Petar 'PetarV' Velickovic
Algorithm: Dijkstra's Algorithm
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <complex>
#define MAX_N 100001
#define INF 987654321
using namespace std;
typedef long long lld;
int n;
struct Node
{
int dist;
vector<int> adj;
vector<int> weight;
};
Node graf[MAX_N];
bool mark[MAX_N];
struct pq_entry
{
int node, dist;
bool operator <(const pq_entry &a) const
{
if (dist != a.dist) return (dist > a.dist); // get the smallest value, due to greater than
return (node > a.node);
}
};
//Dijkstrin algoritam za nalazenje duzina najkracih puteva iz jednog izvora u grafu
//Slozenost: O((V+E)log V)
inline void Dijkstra(int source)
{
priority_queue<pq_entry> pq;
pq_entry P;
for (int i=0;i<n;i++)
{
if (i == source)
{
graf[i].dist = 0;
P.node = i;
P.dist = 0;
pq.push(P);
}
else graf[i].dist = INF;
} //initialise the date,
while (!pq.empty())
{
pq_entry curr = pq.top();// get the least number
pq.pop();
int nod = curr.node;
int dis = curr.dist;
for (int i=0;i<graf[nod].adj.size();i++)
{
if (!mark[graf[nod].adj[i]])// iterate all adjacent notes
{
int nextNode = graf[nod].adj[i];
if (dis + graf[nod].weight[i] < graf[nextNode].dist)
{
graf[nextNode].dist = dis + graf[nod].weight[i];
P.node = nextNode;
P.dist = graf[nextNode].dist;
pq.push(P);
}
}
}
mark[nod] = true;
}
}
int main()
{
n = 4;
graf[0].adj.push_back(1);
graf[0].weight.push_back(5);
graf[1].adj.push_back(0);
graf[1].weight.push_back(5);
graf[1].adj.push_back(2);
graf[1].weight.push_back(5);
graf[2].adj.push_back(1);
graf[2].weight.push_back(5);
graf[2].adj.push_back(3);
graf[2].weight.push_back(5);
graf[3].adj.push_back(2);
graf[3].weight.push_back(5);
graf[3].adj.push_back(1);
graf[3].weight.push_back(6);
graf[1].adj.push_back(3);
graf[1].weight.push_back(6);
Dijkstra(0);
printf("%d\n",graf[3].dist);
return 0;
}
4.Floyd-Warshall Algorithm
/*
Petar 'PetarV' Velickovic
Algorithm: Floyd-Warshall Algorithm
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <complex>
#define MAX_N 300
#define INF 987654321
using namespace std;
typedef long long lld;
int n;
int dist[MAX_N][MAX_N];
int flojd[MAX_N][MAX_N];
//Floyd-Warshallov algoritam za trazenje duzina najkracih puteva svih parova cvorova u grafu
//Slozenost: O(V^3)
inline void FloydWarshall()
{
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
flojd[i][j] = dist[i][j];
}
flojd[i][i] = 0;
}
for (int k=1;k<=n;k++)
{
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
if (flojd[i][k] + flojd[k][j] < flojd[i][j])
{
flojd[i][j] = flojd[i][k] + flojd[k][j];
}
}
}
}
}
int main()
{
n = 3;
dist[1][1] = 0, dist[1][2] = 3, dist[1][3] = INF;
dist[2][1] = INF, dist[2][2] = 0, dist[2][3] = 4;
dist[3][1] = INF, dist[3][2] = 1, dist[3][3] = 0;
FloydWarshall();
printf("%d\n",flojd[1][3]);
return 0;
}
5.Ford-Fulkerson Algorithm
经典讲解:https://www.youtube.com/watch?v=GiN3jRdgxU4
typical concepts of the flow network:
/*
Petar 'PetarV' Velickovic
Algorithm: Ford-Fulkerson Algorithm
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <complex>
#define MAX_N 500
#define INF 987654321
using namespace std;
typedef long long lld;
struct Node
{
vector<int> adj;
};
Node graf[MAX_N];
bool mark[MAX_N];
int cap[MAX_N][MAX_N];
int parent[MAX_N];
int v, e;
int s, t;
//Ford-Fulkersonov algoritam za nalazenje maksimalnog protoka izmedju dva cvora u grafu
//Moze se koristiti i za nalazenje maksimalnog matchinga
//Slozenost: O(E * maxFlow)
inline int DFS()
{
int ret = 0;
for (int i=1;i<=v;i++) parent[i] = 0;
stack<int> dfs_stek;
stack<int> minCapacity;
parent[s] = -1;
dfs_stek.push(s);
minCapacity.push(INF);
while (!dfs_stek.empty())
{
int xt = dfs_stek.top();
int mt = minCapacity.top();
dfs_stek.pop();
minCapacity.pop();
if (xt == t)
{
ret = mt;
break;
}
for (int i=0;i<graf[xt].adj.size();i++)
{
int xt1 = graf[xt].adj[i];
if (cap[xt][xt1] > 0 && parent[xt1] == 0)
{
dfs_stek.push(xt1);
minCapacity.push(min(mt,cap[xt][xt1]));
parent[xt1] = xt;
}
}
}
if (ret > 0)
{
int currNode = t;
while (currNode != s)
{
cap[parent[currNode]][currNode] -= ret;
cap[currNode][parent[currNode]] += ret;
currNode = parent[currNode];
}
}
return ret;
}
inline int FordFulkerson()
{
int flow = 0;
while (true)
{
int currFlow = DFS();
if (currFlow == 0) break;
else flow += currFlow;
}
return flow;
}
int main()
{
v = 4, e = 5;
s = 1, t = 4;
graf[1].adj.push_back(2);
graf[2].adj.push_back(1);
cap[1][2] = 40;
graf[1].adj.push_back(4);
graf[4].adj.push_back(1);
cap[1][4] = 20;
graf[2].adj.push_back(4);
graf[4].adj.push_back(2);
cap[2][4] = 20;
graf[2].adj.push_back(3);
graf[3].adj.push_back(2);
cap[2][3] = 30;
graf[3].adj.push_back(4);
graf[4].adj.push_back(3);
cap[3][4] = 10;
printf("%d\n",FordFulkerson());
return 0;
}
6.Bellman-Ford Algorithm
/*
Petar 'PetarV' Velickovic
Algorithm: Bellman-Ford Algorithm
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <complex>
#define MAX_N 5001
#define MAX_E 25000001
#define INF 987654321
using namespace std;
typedef long long lld;
int v, e;
int dist[MAX_N];
struct Edge
{
int x, y, weight;
};
Edge E[MAX_N];
//Bellman-Ford algoritam za trazenje najkracih puteva iz odredjenog cvora u grafu (graf moze imati i negativne ivice)
//Slozenost: O(V*E)
inline int BellmanFord(int source)
{
for (int i=0;i<v;i++)
{
if (i == source) dist[i]=0;
else dist[i] = INF;
}
bool done = false;
for (int i=0;!done&&i<v;i++)
{
done = true;
for (int j=0;j<e;j++)
{
int so = E[j].x;
int de = E[j].y;
cout<<"dist[so "<<so<<"]="<<dist[so]<<endl;
cout<<"dist[de "<<de<<"]="<<dist[de]<<" weight="<<E[j].weight<<endl;
if (dist[so] + E[j].weight < dist[de])
{
dist[de] = dist[so] + E[j].weight;
done=false;
cout<<"<<<<<<<<<<<<<<"<<endl;
}
cout<<"-------------dist[de"<<de<<"]="<<dist[de]<<endl;
cout<<"-------------dist[so"<<so<<"]="<<dist[so]<<endl;
cout<<"j="<<j<<endl;
}
cout<<"---done="<<done<<endl;
}
if (!done) return -1; //negative edge cycle detected
return 0;
}
int main()
{
v = 4, e = 8;
E[0].x = 0, E[0].y = 1, E[0].weight = 5;
E[1].x = 1, E[1].y = 0, E[1].weight = 5;
E[2].x = 1, E[2].y = 2, E[2].weight = 5;
E[3].x = 2, E[3].y = 1, E[3].weight = 5;
E[4].x = 2, E[4].y = 3, E[4].weight = 5;
E[5].x = 3, E[5].y = 2, E[5].weight = 5;
E[6].x = 3, E[6].y = 1, E[6].weight = 6;
E[7].x = 1, E[7].y = 3, E[7].weight = 6;
BellmanFord(0);
printf("%d\n",dist[3]);
return 0;
}