Skip to content

Commit 9faf129

Browse files
committed
🚀 05-Sep-2020
1 parent 77435fb commit 9faf129

9 files changed

+611
-22
lines changed
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include<bits/stdc++.h>
2+
using namespace std;
3+
4+
#define INF INT_MAX
5+
6+
void bellmanFord(vector<vector<int> > &edges, int v, int src){
7+
int e=edges.size();
8+
vector<int> dist(v, INF);
9+
10+
dist[src]=0;
11+
12+
for(int i=1;i<=v-1;i++){
13+
for(int j=0;j<e;j++){
14+
int u=edges[j][0];
15+
int v=edges[j][1];
16+
int w=edges[j][2];
17+
18+
if(dist[v]>dist[u]+w)
19+
dist[v]=dist[u]+w;
20+
}
21+
}
22+
23+
//If we get a shorter path, then there is a cycle.
24+
for(int j=0;j<e;j++){
25+
int u=edges[j][0];
26+
int v=edges[j][1];
27+
int w=edges[j][2];
28+
29+
if(dist[u]!=INF && dist[v]>dist[u]+w){
30+
cout<<"Graph contains negative weight cycle"<<endl;
31+
return;
32+
}
33+
34+
}
35+
36+
cout<<"Vertex Distance"<<endl;
37+
for(int i=0;i<v;i++){
38+
cout<<i<<" "<<dist[i]<<endl;
39+
}
40+
41+
}
42+
43+
int main(){
44+
ios_base::sync_with_stdio(false);
45+
cin.tie(NULL);
46+
int v=5;
47+
vector<vector<int> > edges { { 0, 1, -1 }, { 0, 2, 4 }, { 1, 2, 3 }, { 1, 3, 2 }, { 1, 4, 2 }, { 3, 2, 5 }, { 3, 1, 1 }, { 4, 3, -3 } }; // u, v, w
48+
bellmanFord(edges, v, 0); // <edges, v, source>
49+
}
50+
51+
52+
53+
// Time Complexity: O(VE)

algorithms/graph/dijkstras_algorithm.cpp

+81
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Priority Queue Implementation
2+
13
#include<bits/stdc++.h>
24
using namespace std;
35

@@ -49,3 +51,82 @@ int main(){
4951
}
5052
dijkstras(adj, v, 0); // source is 0
5153
}
54+
55+
56+
57+
58+
59+
60+
61+
62+
63+
/*
64+
Set implementation
65+
66+
67+
#include<bits/stdc++.h>
68+
using namespace std;
69+
70+
#define INF INT_MAX
71+
typedef pair<int, int> iPair;
72+
73+
void adjListGraph(vector<pair<int, int> > adj[], int s, int d, int w){
74+
// undirected graph
75+
adj[s].push_back({d, w});
76+
adj[d].push_back({s, w});
77+
}
78+
79+
void dijkstras(vector<pair<int, int> > adj[], int V,int src){
80+
set< pair<int, int> > s;
81+
82+
vector<int> dist(V, INF);
83+
84+
dist[src] = 0;
85+
s.insert({dist[src], src});
86+
87+
while (!s.empty()){
88+
pair<int, int> tmp = *(s.begin());
89+
s.erase(s.begin());
90+
91+
int u = tmp.second;
92+
93+
for(auto it : adj[u]){
94+
int v = it.first;
95+
int w = it.second;
96+
97+
if(dist[v] > dist[u] + w){
98+
if(dist[v] != INF)
99+
s.erase(s.find({dist[v], v}));
100+
101+
dist[v] = dist[u] + w;
102+
s.insert({dist[v], v});
103+
}
104+
}
105+
}
106+
107+
108+
cout<<endl;
109+
cout<<"Vertex Distance"<<endl;
110+
for(int i=0;i<V;i++){
111+
cout<<i<<" "<<dist[i]<<endl;
112+
}
113+
}
114+
115+
116+
int main(){
117+
ios_base::sync_with_stdio(false);
118+
cin.tie(NULL);
119+
int v,e;
120+
cin>>v>>e;
121+
vector<pair<int, int> > adj[v];
122+
while(e--){
123+
int s,d,w;
124+
cin>>s>>d>>w;
125+
adjListGraph(adj,s,d,w);
126+
}
127+
dijkstras(adj, v, 0); // source is 0
128+
}
129+
130+
131+
132+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
4+
#define INF INT_MAX
5+
#define V 4
6+
7+
8+
void floydWarshall(int graph[][V]){
9+
int dist[V][V]; // resultant matrix
10+
11+
// Initialize dist matrix, similar to given matrix
12+
for(int i = 0; i < V; i++)
13+
for(int j = 0; j < V; j++)
14+
dist[i][j] = graph[i][j];
15+
16+
for(int k = 0; k < V; k++){
17+
// Pick all vertices as source one by one
18+
for(int i = 0; i < V; i++){
19+
// Pick all vertices as destination for the above picked source
20+
for (int j = 0; j < V; j++){
21+
// If vertex k is on the shortest path from
22+
// i to j, then update the value of dist[i][j]
23+
if(dist[i][k]!=INF && dist[k][j]!=INF && dist[i][k] + dist[k][j] < dist[i][j])
24+
dist[i][j] = dist[i][k] + dist[k][j];
25+
}
26+
}
27+
}
28+
29+
// Print the shortest distance matrix
30+
for(int i = 0; i < V; i++){
31+
for (int j = 0; j < V; j++){
32+
if (dist[i][j] == INF)
33+
cout<<"INF"<<" ";
34+
else
35+
cout<<dist[i][j]<<" ";
36+
}
37+
cout<<endl;
38+
}
39+
}
40+
41+
int main(){
42+
43+
/*
44+
10
45+
(0)------->(3)
46+
| /|\
47+
5 | |
48+
| | 1
49+
\|/ |
50+
(1)------->(2)
51+
52+
*/
53+
54+
int graph[V][V] = { {0, 5, INF, 10},
55+
{INF, 0, 3, INF},
56+
{INF, INF, 0, 1},
57+
{INF, INF, INF, 0}
58+
};
59+
60+
floydWarshall(graph);
61+
return 0;
62+
}
63+
64+
65+
66+
// Time Complexity: O(V^3)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include<bits/stdc++.h>
2+
using namespace std;
3+
4+
struct Edge {
5+
int src, dst, weight;
6+
};
7+
8+
9+
class DisjointSet {
10+
unordered_map<int, int> parent;
11+
public:
12+
13+
void makeSet(int V){
14+
// create V disjoint sets (one for each vertex)
15+
for(int i = 0; i < V; i++)
16+
parent[i] = i;
17+
}
18+
19+
// Find the root of the set in which element k belongs
20+
int Find(int k){
21+
// if k is root
22+
if (parent[k] == k)
23+
return k;
24+
25+
// recur for parent until we find root
26+
return Find(parent[k]);
27+
}
28+
29+
void Union(int a, int b){
30+
// find root of the sets in which elements x and y belongs
31+
int x = Find(a);
32+
int y = Find(b);
33+
34+
parent[x] = y;
35+
}
36+
};
37+
38+
39+
vector<Edge> Kruskals(vector<Edge> edges, int V){
40+
// stores edges present in MST
41+
vector<Edge> MST;
42+
43+
// initialize DisjointSet class
44+
DisjointSet ds;
45+
46+
// create singleton set for each element of universe
47+
ds.makeSet(V);
48+
49+
// MST contains exactly V-1 edges
50+
while (MST.size() != V - 1){
51+
// consider next edge with minimum weight from the graph
52+
Edge next_edge = edges.back();
53+
edges.pop_back();
54+
55+
// find root of the sets to which two endpoint
56+
// vertices of next_edge belongs
57+
int x = ds.Find(next_edge.src);
58+
int y = ds.Find(next_edge.dst);
59+
60+
// if both endpoints have different parents, they belong to
61+
// different connected components and can be included in MST
62+
if (x != y)
63+
{
64+
MST.push_back(next_edge);
65+
ds.Union(x, y);
66+
}
67+
}
68+
return MST;
69+
}
70+
71+
72+
bool comp(Edge a, Edge b){
73+
return (a.weight > b.weight);
74+
}
75+
76+
77+
int main(){
78+
vector<Edge> edges {{ 0, 1, 4 }, { 0, 7, 8 }, { 1, 2, 8 }, { 1, 7, 11 }, { 2, 3, 7 }, { 2, 8, 2 }, { 2, 5, 4 }, { 3, 4, 9 }, { 3, 5, 14 }, { 4, 5, 10 }, { 5, 6, 2 }, {6, 7, 1}, {6, 8, 6}, {7, 8, 7} };
79+
80+
// sort edges by increasing weight
81+
sort(edges.begin(), edges.end(), comp);
82+
83+
int V = 9; // vertices
84+
85+
// construct graph
86+
vector<Edge> e = Kruskals(edges, V);
87+
88+
for (auto &edge: e)
89+
cout << "(" << edge.src << ", " << edge.dst << ", "
90+
<< edge.weight << ")" << endl;
91+
92+
return 0;
93+
}

algorithms/graph/prims_mst_algorithm.cpp

+17-22
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
11
/*
22
Steps
3-
1) Initialize keys of all vertices as infinite and
4-
parent of every vertex as -1.
3+
1) Initialize keys of all vertices as infinite and parent of every vertex as -1.
4+
For ie; for u---> v, Parent stores the u and v is the index of Parent array.
55
6-
2) Create an empty priority_queue pq. Every item
7-
of pq is a pair (weight, vertex). Weight (or
8-
key) is used used as first item of pair
9-
as first item is by default used to compare
10-
two pairs.
6+
2) Create an empty priority_queue pq.
7+
Every item of pq is a pair (weight, vertex).
8+
Weight aka key is used as first item of pair as first item is by default used to compare two pairs.
119
1210
3) Initialize all vertices as not part of MST yet.
1311
We use boolean array inMST[] for this purpose.
14-
This array is required to make sure that an already
15-
considered vertex is not included in pq again. This
16-
is where Ptim's implementation differs from Dijkstra.
17-
In Dijkstr's algorithm, we didn't need this array as
18-
distances always increase. We require this array here
19-
because key value of a processed vertex may decrease
20-
if not checked.
12+
This array is required to make sure that an already considered vertex is not included in pq again.
13+
This is where Prim's implementation differs from Dijkstra.
14+
In Dijkstra's algorithm, we don't need this array as distances always increase.
15+
We require this array here because key value of a processed vertex may decrease if not checked.
2116
2217
4) Insert source vertex into pq and make its key as 0.
2318
@@ -27,14 +22,13 @@ Steps
2722
2823
b) Include u in MST using inMST[u] = true.
2924
30-
c) Loop through all adjacent of u and do
31-
following for every vertex v.
25+
c) Loop through all adjacent of u and do following for every vertex v.
3226
3327
// If weight of edge (u,v) is smaller than
3428
// key of v and v is not already in MST
35-
If inMST[v] = false && key[v] > weight(u, v)
29+
If inMST[v] == false && key[v] > weight(u, v)
3630
37-
(i) Update key of v, i.e., do
31+
(i) Update key of v, ie, do
3832
key[v] = weight(u, v)
3933
(ii) Insert v into the pq
4034
(iv) parent[v] = u
@@ -59,9 +53,8 @@ void adjListGraph(vector<pair<int, int> > adj[], int s, int d, int w){
5953
adj[d].push_back({s, w});
6054
}
6155

62-
void prims(vector<pair<int, int> > adj[], int V){
56+
void prims(vector<pair<int, int> > adj[], int V, int src){
6357
priority_queue<iPair, vector<iPair>, greater<iPair> > pq; // min heap
64-
int src=0;
6558
vector<int> key(V, INF); // weights
6659
vector<int> parent(V, -1); // u ----> v edge then u is parent of v
6760
vector<bool> inMST(V,false); // keep track of vertices included in MST
@@ -70,7 +63,7 @@ void prims(vector<pair<int, int> > adj[], int V){
7063
key[src]=0; // and initialize its key as 0
7164

7265
while(!pq.empty()){
73-
int u=pq.top().second; // pait< key, vertex>
66+
int u=pq.top().second; // pair< key, vertex>
7467
pq.pop();
7568
inMST[u]=true;
7669
for(auto x: adj[u]){
@@ -102,5 +95,7 @@ int main(){
10295
cin>>s>>d>>w;
10396
adjListGraph(adj,s,d,w);
10497
}
105-
prims(adj, v);
98+
prims(adj, v, 0); // <adj, v, source>
99+
100+
return 0;
106101
}

0 commit comments

Comments
 (0)