diff --git a/src/10nodes_output.txt b/src/10nodes_output.txt
new file mode 100644
index 0000000000000000000000000000000000000000..aaf259b44650d1717045055729d09ebee289a0af
--- /dev/null
+++ b/src/10nodes_output.txt
@@ -0,0 +1,10 @@
+0	8	9	7	1	1	5	9	8	3	
+8	0	10	7	7	9	3	1	6	9	
+9	10	0	11	9	10	12	11	9	11	
+7	7	11	0	6	8	4	8	7	6	
+1	7	9	6	0	2	4	8	7	2	
+1	9	10	8	2	0	6	10	9	4	
+5	3	12	4	4	6	0	4	3	6	
+9	1	11	8	8	10	4	0	7	10	
+8	6	9	7	7	9	3	7	0	9	
+3	9	11	6	2	4	6	10	9	0	
diff --git a/src/4nodes_output.txt b/src/4nodes_output.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6a5c68bff01488b31ac6b58e064366b45cc91583
--- /dev/null
+++ b/src/4nodes_output.txt
@@ -0,0 +1,4 @@
+0	10	9	11	
+10	0	1	1	
+9	1	0	2	
+11	1	2	0	
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..6396eab27480e8b1e2ad3dc41264ab5e22fedde9
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,2 @@
+main_omp_v1: main_omp_v1.c
+	gcc main_omp_v1.c data_structure.c -lm -o main_omp_v1 -fopenmp
diff --git a/src/data_structure.c b/src/data_structure.c
new file mode 100644
index 0000000000000000000000000000000000000000..903a15016d5ece26ced69b1e7ef0c15ebef09668
--- /dev/null
+++ b/src/data_structure.c
@@ -0,0 +1,105 @@
+#include "data_structure.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+void createMatrix(int r, int c, matrix* M){
+	mem(*M) =(int*) malloc(((r * c) + 2) * sizeof(int));
+	row(*M) = r;
+	column(*M) = c;
+}
+
+void resetMatrix(matrix *M, int value){
+	for (int i = 0; i < row(*M); i++){
+		for (int j = 0; j < row(*M); j++){
+			if (i == j){
+				setValue(M, i, j, ZERO);
+			}
+			else{
+				setValue(M, i, j, value);
+			}
+		}
+	}
+}
+
+void printMatrix(matrix M){
+	for (int i = 0; i < row(M); i++){
+		for (int j = 0; j < column(M); j++){
+			printf("%d\t", value(M, i, j));
+		}
+		printf("\n");
+	}
+}
+
+void setValue(matrix *M, int i, int j, int value){
+	value(*M, i, j) = value;
+}
+
+void updateMatrix(matrix *M, int* distance){
+	int src = distance[0];
+	for (int dest = 0; dest < row(*M); dest++){
+		if (distance[3 + dest] < value(*M, src, dest) && src != dest){
+			value(*M, src, dest) = distance[3 + dest];
+			value(*M, dest, src) = distance[3 + dest];
+		}
+	}
+}
+
+// void updateDistance(matrix *M, int* distance){
+
+// }
+
+int* serializeMatrix(matrix M){
+	return mem(M);	
+}
+
+void printSerializedMatrix(int* SM){
+	for (int i = 0; i < SM[0]; i++){
+		for (int j = 0; j < SM[1]; j++){
+			printf("%d ", SM[2 + (i * SM[0]) + j]);
+		}
+		printf("\n");
+	}
+}
+
+void setMatrix(matrix *M){
+	setValue(M, 0, 1, 4);
+	setValue(M, 0, 7, 8);
+	
+	setValue(M, 1, 0, 4);
+	setValue(M, 1, 2, 8);
+	setValue(M, 1, 7, 11);
+
+	setValue(M, 2, 1, 8);
+	setValue(M, 2, 3, 7);
+	setValue(M, 2, 5, 4);
+	setValue(M, 2, 8, 2);
+
+	setValue(M, 3, 2, 7);
+	setValue(M, 3, 4, 9);
+	setValue(M, 3, 5, 14);
+
+	setValue(M, 4, 3, 9);
+	setValue(M, 4, 5, 10);
+	
+	setValue(M, 5, 2, 4);
+	setValue(M, 5, 3, 14);
+	setValue(M, 5, 4, 10);
+	setValue(M, 5, 6, 2);
+
+	setValue(M, 6, 5, 2);
+	setValue(M, 6, 7, 1);
+	setValue(M, 6, 8, 6);
+
+	setValue(M, 7, 0, 8);
+	setValue(M, 7, 1, 11);
+	setValue(M, 7, 6, 1);
+	setValue(M, 7, 8, 7);
+
+	setValue(M, 8, 2, 2);
+	setValue(M, 8, 6, 6);
+	setValue(M, 8, 7, 7);
+}
+
+void destroyMatrix(matrix *M){
+	free(mem(*M));
+}
\ No newline at end of file
diff --git a/src/data_structure.h b/src/data_structure.h
new file mode 100644
index 0000000000000000000000000000000000000000..deef19bb2f6e575df5b34178d6b3979a4599f791
--- /dev/null
+++ b/src/data_structure.h
@@ -0,0 +1,29 @@
+#ifndef DATA_STRUCTURE_H
+#define DATA_STRUCTURE_H
+
+
+typedef struct {
+	int* mem;
+} matrix;
+
+// Selektor
+#define mem(M) (M).mem
+// Ukuran
+#define row(M) (M).mem[0]
+#define column(M) (M).mem[1]
+#define value(M, i, j) (M).mem[2 + (i*row(M)) + (j)]
+#define INF 99999
+#define ZERO 0
+
+void createMatrix(int r, int c, matrix* M);
+void printMatrix(matrix M);
+void resetMatrix(matrix *M, int value);
+void setValue(matrix *M, int i, int j, int value);
+void updateMatrix(matrix *M, int* distance);
+void setMatrix(matrix *M);
+
+int* serializeMatrix(matrix M);
+void printSerializedMatrix(int* SM);
+void destroyMatrix(matrix *M);
+
+#endif
\ No newline at end of file
diff --git a/src/data_structure_serial.c b/src/data_structure_serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..999b9265e76e6e2a256991ac3d0461b7a6cd2fa7
--- /dev/null
+++ b/src/data_structure_serial.c
@@ -0,0 +1,79 @@
+#include "data_structure_serial.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+void createMatrix(int r, int c, matrix *M)
+{
+	row(*M) = r;
+	column(*M) = c;
+	Mem(*M) = (int **)malloc(row(*M) * sizeof(int *));
+
+	for (int i = 0; i < row(*M); i++)
+	{
+		M->mem[i] = (int *)malloc(column(*M) * sizeof(int));
+	}
+}
+
+void destroyMatrix(matrix *M)
+{
+	for (int i = 0; i < row(*M); i++)
+	{
+		free(M->mem[i]);
+	}
+	free(M->mem);
+}
+
+void resetMatrix(matrix *M, int value)
+{
+	for (int i = 0; i < row(*M); i++)
+	{
+		for (int j = 0; j < column(*M); j++)
+		{
+			if (i == j)
+			{
+				setValue(M, i, j, ZERO);
+			}
+			else
+			{
+				setValue(M, i, j, value);
+			}
+		}
+	}
+}
+
+void printMatrix(matrix M)
+{
+	for (int i = 0; i < row(M); i++)
+	{
+		for (int j = 0; j < column(M); j++)
+		{
+			
+			printf("%d ", value(M, i, j));
+			// printf("Ngeprint col %d\n", j);
+			// printf("Ngeprint row %d\n", i);
+			// printf("%d ", M.mem[i][j]);
+		}
+		printf("\n");
+	}
+}
+
+void setValue(matrix *M, int i, int j, int value)
+{
+	value(*M, i, j) = value;
+}
+
+void updateMatrix(matrix *M, matrix m, int src)
+{
+	for (int dest = 0; dest < row(m); dest++)
+	{
+		// printf("VALUE DISTANCE %d %d \n", dest, (value(m, dest, 0)));
+		// printf("MATRIX SOLU %d %d %d \n", src, dest, (value(*M, src, dest)));
+		if ((value(m, dest, 0) < value(*M, src, dest)) && (src != dest))
+		{
+			setValue(M, src, dest, value(m, dest, 0));
+			setValue(M, dest, src, value(m, dest, 0));
+			// value(*M, src, dest) = value(m, dest, 0);
+			// value(*M, dest, src) = value(m, dest, 0);
+		}
+	}
+}
diff --git a/src/data_structure_serial.h b/src/data_structure_serial.h
new file mode 100644
index 0000000000000000000000000000000000000000..da637cee0c6f7d882a7579f82596ae4db9e769e4
--- /dev/null
+++ b/src/data_structure_serial.h
@@ -0,0 +1,28 @@
+#ifndef DATA_STRUCTURE_SERIAL_H
+#define DATA_STRUCTURE_SERIAL_H
+
+typedef struct
+{
+	int **mem;
+	int row;
+	int column;
+} matrix;
+
+// Selektor
+#define Mem(M) (M).mem
+// Ukuran
+#define row(M) (M).row
+#define column(M) (M).column
+#define value(M, i, j) (M).mem[(i)][(j)]
+#define INF 99999
+#define ZERO 0
+
+void createMatrix(int r, int c, matrix *M);
+void destroyMatrix(matrix *M);
+void printMatrix(matrix M);
+void resetMatrix(matrix *M, int value);
+void setValue(matrix *M, int i, int j, int value);
+
+void updateMatrix(matrix *M, matrix m, int src);
+
+#endif
diff --git a/src/main_omp_v1 b/src/main_omp_v1
new file mode 100755
index 0000000000000000000000000000000000000000..bfc79f91db7a7a60d8fbe5ee1cadd22b91f14f1d
Binary files /dev/null and b/src/main_omp_v1 differ
diff --git a/src/main_omp_v1.c b/src/main_omp_v1.c
new file mode 100644
index 0000000000000000000000000000000000000000..88a95cf76b8c0594c8e06556208900ccb19a296b
--- /dev/null
+++ b/src/main_omp_v1.c
@@ -0,0 +1,156 @@
+#include "data_structure.h"
+#include <omp.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int minDistance(int* distance, int visitedNodes[], int sz){
+	int min_value = INF;
+	int min_index = 0;
+	for (int i = 0; i < sz; i++){
+		if ((distance[3 + i] <= min_value) && (visitedNodes[i] != 1)){
+			min_index = i;
+			min_value = distance[3 + i];
+		}
+	}
+	return min_index;
+}
+
+int normalize(int rand){
+	
+	rand = (rand % (20 - 1)) + 1;
+
+	return rand;
+}
+
+void randomize(matrix *M, int NIM){
+	srand(NIM);
+
+	for (int row = 0; row < row(*M); row++){
+		for (int column = 0; column < column(*M); column++){
+			if (column > row){
+				int temp = normalize(rand());
+
+				value(*M, row, column) = temp;
+				value(*M, column, row) = temp;
+			}
+		}	
+	}
+}
+
+void dijsktra(matrix graph, int* distance, int src){
+
+	int nNodes = row(graph);
+	// Current Node with minimum distance to SRC
+	int currentNode;
+	int visitedNodes[nNodes];
+
+
+	// Init distance to INFINITY
+	for (int j = 0; j < nNodes; j++){
+		distance[3 + j] = INF;
+		visitedNodes[j] = 0;
+	}
+
+	// Distance to itself is 0
+	distance[3 + src] = 0;
+
+	for (int n = 0; n < nNodes - 1; n++){
+		// Pick the minimum distance from current nodes
+		currentNode = minDistance(distance, visitedNodes, nNodes);
+
+		visitedNodes[currentNode] = 1;
+
+		for (int v = 0; v < nNodes; v++){
+			if (visitedNodes[v] == 0 &&
+				value(graph, currentNode, v) != INF &&
+				distance[3 + currentNode] != INF &&
+				distance[3 + currentNode]+ value(graph, currentNode, v) < distance[3 + v]
+				){
+				distance[3 + v] = distance[3 + currentNode] + value(graph, currentNode, v);
+			}
+		}
+	}
+	distance[2] = 1;
+}
+
+void filewrite(matrix *M, int nNodes){
+   	FILE * fp;
+   	int i;
+   	/* open the file for writing*/
+	char strint[10];
+	sprintf(strint, "%d", nNodes);
+   	fp = fopen (strcat(strint,"nodes_output.txt"),"w");
+	
+	for (int i = 0; i < row(*M); i++){
+		for (int j = 0; j < column(*M); j++){
+			fprintf (fp, "%d\t", value(*M, i, j));
+		}
+		fprintf(fp, "\n");
+	}
+   	/* close the file*/  
+   	fclose (fp);
+   
+}
+
+
+void parallelDijsktra(int nNodes, int NUM_THREADS){
+	
+	double startTime = 0.0, totalTime = 0.0;
+	int buff, temp;
+
+	matrix M;
+	matrix Solu;
+	createMatrix(nNodes, nNodes, &M);
+	resetMatrix(&M, INF);
+
+	createMatrix(nNodes, nNodes, &Solu);
+	resetMatrix(&Solu, INF);	
+	randomize(&M, 13517124);
+
+	startTime = omp_get_wtime();
+	int factor = ceil((double) nNodes/(NUM_THREADS));
+
+# pragma omp parallel num_threads(NUM_THREADS) shared(Solu, M, factor, startTime, nNodes)
+{
+	int i = 0;
+
+	int currentNode = (omp_get_thread_num() * factor);
+
+	int* distance;
+	distance = (int *) malloc((3 + nNodes) * sizeof(int));
+	distance[1] = nNodes;
+	distance[2] = 0;
+
+	//printf("Thread #%d ngurus node: ", omp_get_thread_num());
+	while (i < factor && currentNode < nNodes){
+		distance[0] = currentNode;
+		dijsktra(M, distance, currentNode);
+		updateMatrix(&Solu, distance);
+		i += 1;
+		currentNode = i + (omp_get_thread_num() * factor);
+	}
+
+	//printf("thread #%d finished\n", omp_get_thread_num());
+	free(distance);
+}
+# pragma omp barrier
+	totalTime = omp_get_wtime() - startTime;
+	printf("PEPEG\n");
+	// printMatrix(Solu);
+	printf("Process completed in %f microseconds\n", totalTime*1000);
+	filewrite(&Solu, nNodes);
+	destroyMatrix(&Solu);
+}
+
+int main(){
+	// Banyak Nodes, Banyak Threads
+	int N, NUM_THREADS;
+	printf("Banyak Node: ");
+	scanf("%d", &N);
+	printf("Banyak Threads: ");
+	scanf("%d", &NUM_THREADS);
+	parallelDijsktra(N, NUM_THREADS);
+	return 0;
+}
\ No newline at end of file
diff --git a/src/mainserial b/src/mainserial
new file mode 100755
index 0000000000000000000000000000000000000000..2816c63d8ce344ee776ff3d0ccc7e9f8b2f4809c
Binary files /dev/null and b/src/mainserial differ
diff --git a/src/mainserial.c b/src/mainserial.c
new file mode 100644
index 0000000000000000000000000000000000000000..cbe7333efb4ef919123adedf7836763cc7b182ae
--- /dev/null
+++ b/src/mainserial.c
@@ -0,0 +1,159 @@
+#include "data_structure_serial.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+// #include "mpi.h"
+int normalize(int rand){
+	
+	rand = (rand % (20 - 1)) + 1;
+
+	return rand;
+}
+
+void randomize(matrix *M, int NIM){
+	srand(NIM);
+
+	for (int row = 0; row < row(*M); row++){
+		for (int column = 0; column < column(*M); column++){
+			if (column > row){
+				int temp = normalize(rand());
+
+				value(*M, row, column) = temp;
+				value(*M, column, row) = temp;
+			}
+		}	
+	}
+}
+void printSolution(matrix distance, int src)
+{
+	printf("Node Src: %d\n", src);
+	printf("Node Dest       Distance     from\n");
+	for (int i = 0; i < row(distance); i++)
+	{
+		printf("%d              %d         %d\n", i, value(distance, i, 0), value(distance, i, 1));
+	}
+}
+int minDistance(matrix distance, int visitedNodes[], int sz)
+{
+	int min_value = INF;
+	int min_index = 0;
+	for (int i = 0; i < sz; i++)
+	{
+		if (value(distance, i, 0) <= min_value && visitedNodes[i] != 1)
+		{
+			min_index = i;
+			min_value = value(distance, i, 0);
+		}
+	}
+	// printf("MINDEX %d\n", min_index);
+	// printf("MINVAL %d\n", min_value);
+	return min_index;
+}
+matrix dijsktra(matrix graph, int src)
+{
+	int nNodes = row(graph);
+	// Current Node with minimum distance to SRC
+	int currentNode;
+	matrix distance;
+	int visitedNodes[nNodes];
+	createMatrix(nNodes, 2, &distance);
+	// Init distance to INFINITY
+	for (int i = 0; i < nNodes; i++)
+	{
+		value(distance, i, 0) = INF;
+		value(distance, i, 1) = -1;
+		visitedNodes[i] = 0;
+	}
+	// Distance to itself is 0
+	value(distance, src, 0) = 0;
+	for (int n = 0; n < nNodes - 1; n++)
+	{
+		// Pick the minimum distance from current nodes
+		currentNode = minDistance(distance, visitedNodes, nNodes);
+		visitedNodes[currentNode] = 1;
+		for (int v = 0; v < nNodes; v++)
+		{
+			/* printf("[%d, %d]\n", n, v);
+			printf("current Nodes: %d\n", currentNode); */
+			if (visitedNodes[v] == 0 &&
+				value(graph, currentNode, v) != INF &&
+				value(distance, currentNode, 0) != INF &&
+				value(distance, currentNode, 0) + value(graph, currentNode, v) < value(distance, v, 0))
+			{
+				value(distance, v, 0) = value(distance, currentNode, 0) + value(graph, currentNode, v);
+				value(distance, v, 1) = currentNode;
+			}
+		}
+	}
+	// printSolution(distance, src);
+	return distance;
+}
+void generateSolutions(matrix graph)
+{
+	int currentNode;
+	matrix solutions;
+	matrix tempSingleSolution;
+	createMatrix(row(graph), 2, &tempSingleSolution);
+	createMatrix(row(graph), column(graph), &solutions);
+	
+    resetMatrix(&solutions, INF);
+    
+	for (currentNode = 0; currentNode < row(graph); currentNode++)
+	{
+		tempSingleSolution = dijsktra(graph, currentNode);
+		updateMatrix(&solutions, tempSingleSolution, currentNode);
+				
+	}
+	destroyMatrix(&tempSingleSolution);
+	// printMatrix(solutions);
+	destroyMatrix(&solutions);
+}
+
+void filewrite(matrix *M){
+   	FILE * fp;
+   	int i;
+   	/* open the file for writing*/
+   	fp = fopen ("outputserial.txt","w");
+	
+	for (int i = 0; i < row(*M); i++){
+		for (int j = 0; j < column(*M); j++){
+			fprintf (fp, "%d\t", value(*M, i, j));
+		}
+		fprintf(fp, "\n");
+	}
+   	/* close the file*/  
+   	fclose (fp);
+   
+}
+
+int main(int argc, char* argv[])
+{
+    clock_t start, end;
+    double cpu_time_used;
+    
+    matrix M;
+	int nNodes;
+    nNodes = atoi(argv[1]);
+    
+    
+    createMatrix(nNodes, nNodes, &M);
+	resetMatrix(&M, INF);
+
+    randomize(&M, 13517073);
+    // printMatrix(M);
+
+    start = clock();
+
+	generateSolutions(M);
+
+	destroyMatrix(&M);
+
+    end = clock();
+    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+	
+    printf("\nSerial time Elapsed: %f\n", cpu_time_used * 1000000);
+
+    // filewrite(&M);
+
+    return 0;
+}