diff --git a/Makefile b/Makefile
index 768c89c62c48d7fe741f4e8387529ef7ddc9e89a..328cc8af05740a5f437b5b025ad8b6c001d0f1fd 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,18 @@
-.PHONY: all compile run
+.PHONY: all deploy clean
 
-all: compile run
+all: compile deploy run
 
 compile:
 	mpicc src/openmpi.c -o openmpi.out
 
+deploy:
+	scp openmpi.out 13517103@167.205.35.150:~
+
+test:
+	mpirun -np $(shell nproc) openmpi.out
+
 run:
-	mpirun -np nproc --hostfile mpi_hostfile --bind-to core:overload-allowed openmpi.out
+	mpirun -np $(shell nproc) --hostfile mpi_hostfile openmpi.out
+
+clean:
+	rm *.out
\ No newline at end of file
diff --git a/output.txt b/output.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/openmpi.c b/src/openmpi.c
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..38c43513cb3bc41830fb9c86bde562074e041afb 100644
--- a/src/openmpi.c
+++ b/src/openmpi.c
@@ -0,0 +1,198 @@
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#define SEED 13517103
+#define MAX_VALUE -1
+
+void dijkstra(int **G, int n, int startnode, int *distance);
+
+int main(int argc, char *argv[]) {
+  int world_size, rank;
+  int N, i, j, n_proc;
+  float total_time;
+  char file_name[] = "output.txt";;
+  FILE * fp;
+
+  while(1) {
+    printf("Enter no. of vertices: ");
+    scanf("%d", &N);
+
+    if(&N != NULL) break;
+  }
+  
+  n_proc = atoi(argv[2]);
+  printf("%d", n_proc);
+
+  fp = fopen(file_name,"w");
+  
+  int **G = (int **)malloc (N * sizeof(int *));
+  if (G==NULL) {
+    fprintf(stderr, "Usage: memory allocation failed\n");
+    exit(1);
+  }
+
+  for (i=0; i<N; i++) {
+    G[i] = (int *)malloc(N * sizeof(int));
+    if (G[i]==NULL) {
+      fprintf(stderr, "Usage: memory allocation failed\n");
+      exit(1);
+    }
+  }
+
+  int **result = (int **)malloc (N * sizeof(int *));
+  if (result==NULL) {
+    fprintf(stderr, "Usage: memory allocation failed\n");
+    exit(1);
+  }
+
+  for (i=0; i<N; i++) {
+    result[i] = (int *)malloc(N * sizeof(int));
+    if (result[i]==NULL) {
+      fprintf(stderr, "Usage: memory allocation failed\n");
+      exit(1);
+    }
+  }
+  
+  MPI_Init(NULL,NULL);
+  MPI_Comm_size(MPI_COMM_WORLD, &world_size);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+  if (rank == 0) {
+    srand(SEED);
+
+    // Pembangkitan graf
+    for (i=0; i<N; i++) {
+      for (j=0; j<N; j++) {
+        if (i==j)     G[i][j] = MAX_VALUE;
+        else if (i>j) G[i][j] = G[j][i];
+        else          G[i][j] = rand();
+      }
+    }
+
+    MPI_Bcast(G, N*N, MPI_INT, 0, MPI_COMM_WORLD);
+
+    // Result
+    for (i=0; i<N; i++) {
+      for (j=0; j<N; j++) {
+        result[i][j] = 0;
+      }
+    }
+
+    MPI_Bcast(result, N*N, MPI_INT, 0, MPI_COMM_WORLD);
+  }
+
+  int local_size = N / n_proc;
+
+  MPI_Barrier(MPI_COMM_WORLD);
+  total_time -= MPI_Wtime();
+  
+  int *distance = (int*) malloc (N * sizeof(int));
+  if (distance==NULL) {
+    fprintf(stderr, "Usage: memory allocation failed\n");
+    exit(1);
+  }
+  
+  // Dijkstra here
+  for (i=(rank*local_size); i<(rank*local_size+local_size); i++) {
+    dijkstra(G, N, i, distance);
+    
+    for (j=0; j<N; j++) {
+      result[i][j] = distance[j];
+    }
+
+  }
+
+  free(distance);
+  
+  MPI_Barrier(MPI_COMM_WORLD);
+  total_time += MPI_Wtime();
+
+  MPI_Finalize();
+
+  for (i=0; i<N; i++) {
+    for (j=0; j<N; j++) {
+      if (j==N-1) fprintf(fp, "%d\n", result[i][j]);
+      fprintf(fp, "%d ", result[i][j]);
+    }
+  }
+
+  fclose(fp);
+
+  for (i=0; i<N; i++) {
+    free(G[i]);
+  }
+  free(G);
+
+  for (i=0; i<N; i++) {
+    free(result[i]);
+  }
+  free(result);
+
+  return 1;
+}
+
+void dijkstra(int **G, int n, int startnode, int *distance) {
+ int *pred, *visited;
+ int count, min_distance, next_node, i, j;
+
+  pred = (int *) malloc(n*sizeof(int));
+  if (pred==NULL) {
+    fprintf(stderr, "Usage: memory allocation failed\n");
+    exit(1);
+  }
+
+  visited = (int *) malloc(n*sizeof(int));
+  if (visited==NULL) {
+    fprintf(stderr, "Usage: memory allocation failed\n");
+    exit(1);
+  }
+ 
+ // pred[] stores the predecessor of each node
+ // count gives the number of nodes seen so far
+ 
+ // initialize pred[],distance[] and visited[]
+ for (i=0; i<n; i++) {
+  distance[i] = G[startnode][i];
+  pred[i] = startnode;
+  visited[i] = 0;
+ }
+ 
+ distance[startnode] = 0;
+ visited[startnode] = 1;
+ count = 1;
+
+ 
+ while (count < (n-1)) {
+  min_distance = INT_MAX;
+  
+  // next_node gives the node at minimum distance
+  for (i=0; i<n; i++) {
+      if (distance[i]==MAX_VALUE) continue;
+   else if (distance[i]<min_distance && !visited[i]) {
+    min_distance = distance[i];
+    next_node = i;
+      }
+    }
+        
+    // check if a better path exists through next_node   
+    visited[next_node] = 1;
+    for (i=0; i<n; i++) {
+      if (!visited[i]) {
+        if (distance[i]==MAX_VALUE && G[next_node][i]!=MAX_VALUE) {
+          distance[i] = min_distance + G[next_node][i];
+          pred[i] = next_node;
+        }
+        else if (min_distance+G[next_node][i]<distance[i] && G[next_node][i]!=MAX_VALUE) {
+          distance[i] = min_distance + G[next_node][i];
+          pred[i] = next_node;
+        }
+      }
+    }
+  count++;
+ }
+
+  free(pred);
+  free(visited);
+}
\ No newline at end of file