diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..600d2d33badf45cc068e01d2e3c837e11c417bc4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.vscode
\ No newline at end of file
diff --git a/parallel.cu b/parallel.cu
new file mode 100644
index 0000000000000000000000000000000000000000..9bb73d092fb4412851ea9806c39fc3281680f68f
--- /dev/null
+++ b/parallel.cu
@@ -0,0 +1,184 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <time.h>
+#include <omp.h>
+
+#define TRUE 1
+#define FALSE 0
+#define INF LONG_MAX
+// #define N_THREADS 10
+#define OUTPUT_FILE_PATH "parallel_result.txt"
+
+void print_matrix(long matrix[], int n_row, int n_col);
+void print_array(long arr[], int len);
+long *initialize_matrix(int random_number, int n);
+long *initialize_result(int n);
+void write_output(long matrix[], int n_row, int n_col, double time);
+
+__global__
+void dijkstra(int n, long matrix[], long result[]) {
+    printf("Djikstra summoned");
+
+	long *connected;         // Array of 'boolean' on whether vertice [i] is connected to source
+    long *distance;          // Distance of vertice [i] from source
+
+    int my_rank = blockIdx.x * blockDim.x + threadIdx.x;
+    int stride = blockDim.x * gridDim.x;
+
+	connected = (long*)malloc(n * sizeof(long));
+    distance = (long *)malloc(n * sizeof(long));
+
+    printf("rank %d of n %d", my_rank, n);
+
+	for (int SOURCE_V = my_rank; SOURCE_V < n; SOURCE_V += stride) {
+        printf("Now processing for vertice %d.", SOURCE_V);
+
+        for (int i = 0; i < n; i++) {
+            if (i == SOURCE_V) {
+                connected[i] = TRUE;
+            } else {
+                connected[i] = FALSE;
+            }
+        }
+
+        for (int i = 0; i < n; i++) {
+            distance[i] = matrix[SOURCE_V * n + i];
+        }
+        
+        /* Djikstra */
+        for (int i = 1; i < n; i++) {
+            
+            long min_dist = INF;
+            int closest_v = -1;
+            for (int i = 0; i < n; i++) {
+                if (connected[i] != TRUE) {
+                    if (distance[i] < min_dist) {
+                        min_dist = distance[i];
+                        closest_v = i;
+                    }
+                }
+            }
+
+            //printf("Closest vertice is: %d\n", closest_v);
+            connected[closest_v] = TRUE;
+            
+            /* Update distances */
+            /* With unconnected vertices in distance array */
+            for (int j = 0; j < n; j++) {
+                if (connected[j] == FALSE) {
+                    /* If not connected, only concern with distance array */
+                    long new_dist = distance[closest_v] + matrix[closest_v * n + j];
+                    if (new_dist < distance[j]) {
+                        distance[j] = new_dist;
+                    }
+                }
+            }
+            for (int j = 0; j < n; j++) {
+                result[SOURCE_V * n + j] = distance[j];
+            }
+        }
+    }
+
+    free(connected);
+    free(distance);
+}
+
+int main (int argc, char **argv) {
+    long *matrix, *result;          // Matrix size i * j of distance from vertice [i] to vertice [j]
+    int n;                          // Number of vertices
+    // int my_rank, thread_count, sub_n;
+    clock_t start, end;
+    double cpu_time_used;
+    
+    /* Read number of vertices */
+    printf("Number of vertices (n): "); scanf("%d", &n);
+
+    cudaMallocManaged(&matrix, n*sizeof(long));
+    cudaMallocManaged(&result, n*sizeof(long));
+    
+    matrix = initialize_matrix(13517142, n);
+    printf("\nGenerated %d * %d matrix.\n", n, n);
+
+    print_matrix(matrix, n, n);
+
+    result = initialize_result(n);
+
+    start = clock();
+	
+	dijkstra<<<1,1>>>(n, matrix, result);
+
+    cudaDeviceSynchronize();
+
+	end = clock();
+	cpu_time_used = (((double) (end - start)) / CLOCKS_PER_SEC) * 1000000;
+	write_output(result, n, n, cpu_time_used);
+	printf("\nResults written to %s.\n", OUTPUT_FILE_PATH);
+
+	cudaFree(result);
+    cudaFree(matrix);
+}
+
+void print_matrix(long matrix[], int n_row, int n_col) {
+    for (int i = 0; i < n_row; i++) {
+        for (int j = 0; j < n_col; j++) {
+            printf("%ld ", matrix[i * n_col + j]);
+        }
+        printf("\n");
+    }
+}
+
+void print_array(long arr[], int len) {
+    for (int i = 0; i < len; i++) {
+        printf("%ld ", arr[i]);
+    }
+    printf("\n");
+}
+
+void write_output(long matrix[], int n_row, int n_col, double time) {
+    FILE * file;
+    file = fopen (OUTPUT_FILE_PATH,"w");
+    for (int i = 0; i < n_row; i++) {
+        for (int j = 0; j < n_col; j++) {
+            fprintf(file, "%ld ", matrix[i * n_col + j]);
+        }
+        fprintf(file, "\n");
+    }
+    fprintf(file, "Process finished in %f microseconds.\n", time);
+    fclose (file);
+}
+
+long *initialize_matrix(int random_number, int n) {
+    /* Initialize variables */
+    long *matrix = (long *)malloc(sizeof(long) * n*n);
+
+	srand(random_number);
+	for (int i = 0; i < n; i++) {
+		for (int j = 0; j <= i; j++) {
+			if (i == j) {
+				matrix[i * n + j] = 0;
+			} else {
+				long dist = (rand() % 9) + 1;
+				matrix[i * n + j] = dist;
+				matrix[j * n + i] = dist;
+			}
+		}
+	}
+    return matrix;
+}
+
+long *initialize_result(int n) {
+    long *result = (long *)malloc(sizeof(long) * n*n);
+
+    for (int i = 0; i < n; i++) {
+        for (int j = 0; j < n; j++) {
+            if (i == j) {
+                result[i * n + j] = 0;
+            } else {
+                result[i * n + j] = INF;
+            }
+        }
+    }
+
+    return result;
+}
\ No newline at end of file
diff --git a/serial.c b/serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..99e470f8b03b8d80eee04064b65f6bf84dd2ad5a
--- /dev/null
+++ b/serial.c
@@ -0,0 +1,199 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <time.h>
+
+#define TRUE 1
+#define FALSE 0
+#define INF LONG_MAX
+#define OUTPUT_FILE_PATH "serial_result.txt"
+
+void print_matrix(long matrix[], int n_row, int n_col);
+void print_array(long arr[], int len);
+int idx_min_distance(long connd[], long dist[], int len);
+long *initialize_matrix(int random_number, int n);
+long *initialize_result(int n);
+void write_output(long matrix[], int n_row, int n_col, double time);
+
+int main (int argc, char **argv) {
+    long *matrix, *result;   // Matrix size i * j of distance from vertice [i] to vertice [j]
+    long *connected;         // Array of 'boolean' on whether vertice [i] is connected to source [0]
+    long *distance;          // Distance of vertice [i] from source [0]
+    int n;                   // Number of vertices
+
+    /* Read number of vertices */
+    printf("Number of vertices (n): "); scanf("%d", &n);
+
+    matrix = initialize_matrix(13517142, n);
+    printf("\nGenerated %d * %d matrix.\n", n, n);
+    //print_matrix(matrix, n, n);
+
+    result = initialize_result(n);
+    connected = malloc(n * sizeof(long));
+    distance = malloc(n * sizeof(long));
+
+    clock_t start, end;
+    double cpu_time_used;
+    start = clock();
+
+    for (int SOURCE_V = 0; SOURCE_V < n; SOURCE_V++) {
+        for (int i = 0; i < n; i++) {
+            if (i == SOURCE_V) {
+                connected[i] = TRUE;
+            } else {
+                connected[i] = FALSE;
+            }
+        }
+
+        for (int i = 0; i < n; i++) {
+            distance[i] = matrix[SOURCE_V * n + i];
+        }
+        
+        /* Djikstra */
+        for (int i = 1; i < n; i++) {
+            //printf("------------------------------------------------\n");
+            //printf("CONNECTED       : ");
+            //print_array(connected, n);
+            //printf("DISTANCE FROM %d : ", SOURCE_V);
+            //print_array(distance, n);
+
+            int closest_v = idx_min_distance(connected, distance, n);
+            //printf("Closest vertice is: %d\n", closest_v);
+            connected[closest_v] = TRUE;
+            
+            /* Update distances */
+            /* With unconnected vertices in distance array */
+            for (int j = 0; j < n; j++) {
+                if (connected[j] == FALSE) {
+                    /* If not connected, only concern with distance array */
+                    long new_dist = distance[closest_v] + matrix[closest_v * n + j];
+                    if (new_dist < distance[j]) {
+                        distance[j] = new_dist;
+                    }
+                }
+            }
+            
+            /* With connected vertices in result matrix */
+            /* int closest_to_closest_v = SOURCE_V;
+            if (distance[closest_v] != matrix[closest_v * n + SOURCE_V]) {
+                for (int i = 0; i < n; i++) {
+                    if (connected[i] == TRUE && i != closest_v) {
+                        long dist_closest_to_v = matrix[closest_v * n + closest_to_closest_v];
+                        long i_to_v = matrix[closest_v * n + i];
+                        if (i_to_v < dist_closest_to_v) {
+                            closest_to_closest_v = i;
+                        }
+                    }
+                }
+                result[closest_v * n + closest_to_closest_v] = matrix[closest_v * n + closest_to_closest_v];
+                result[closest_to_closest_v * n + closest_v] = matrix[closest_v * n + closest_to_closest_v];
+            }
+            result[closest_v * n + SOURCE_V] = distance[closest_v];
+            result[SOURCE_V * n + closest_v] = distance[closest_v];
+            for (int i = 0; i < n; i++) {
+                if (connected[i] == TRUE && i != closest_v && i != closest_to_closest_v) {
+                    result[closest_v * n + i] = distance[closest_v] + distance[i];
+                    result[i * n + closest_v] = distance[closest_v] + distance[i];
+                }
+            }*/
+        }
+
+        for (int j = 0; j < n; j++) {
+            result[SOURCE_V * n + j] = distance[j];
+        }
+    }
+
+    //printf("\n----------------------RESULTS---------------------\n", n, n);
+    //print_matrix(result, n, n);
+    end = clock();
+    cpu_time_used = (((double) (end - start)) / CLOCKS_PER_SEC) * 1000000;
+    //cpu_time_used = (end - start);
+    write_output(result, n, n, cpu_time_used);
+    printf("\nResults written to %s.\n", OUTPUT_FILE_PATH);
+
+    /* Deallocation */
+    free(matrix);
+    free(result);
+    free(connected);
+    free(distance);
+}
+
+void print_matrix(long matrix[], int n_row, int n_col) {
+    for (int i = 0; i < n_row; i++) {
+        for (int j = 0; j < n_col; j++) {
+            printf("%ld ", matrix[i * n_col + j]);
+        }
+        printf("\n");
+    }
+}
+
+void print_array(long arr[], int len) {
+    for (int i = 0; i < len; i++) {
+        printf("%ld ", arr[i]);
+    }
+    printf("\n");
+}
+
+int idx_min_distance(long connd[], long dist[], int len) {
+    long min_dist = INF;
+    int idx_min_dist = -1;
+    for (int i = 0; i < len; i++) {
+        if (connd[i] != TRUE) {
+            if (dist[i] < min_dist) {
+                min_dist = dist[i];
+                idx_min_dist = i;
+            }
+        }
+    }
+    return idx_min_dist;
+}
+
+void write_output(long matrix[], int n_row, int n_col, double time) {
+    FILE * file;
+    file = fopen (OUTPUT_FILE_PATH,"w");
+    for (int i = 0; i < n_row; i++) {
+        for (int j = 0; j < n_col; j++) {
+            fprintf(file, "%ld ", matrix[i * n_col + j]);
+        }
+        fprintf(file, "\n");
+    }
+    fprintf(file, "Process finished in %f microseconds.\n", time);
+    fclose (file);
+}
+
+
+long *initialize_matrix(int random_number, int n) {
+    /* Initialize variables */
+    long *matrix = malloc(sizeof(long) * n*n);
+    
+    srand(random_number);
+    for (int i = 0; i < n; i++) {
+        for (int j = 0; j <= i; j++) {
+            if (i == j) {
+                matrix[i * n + j] = 0;
+            } else {
+                long dist = rand();
+                matrix[i * n + j] = dist;
+                matrix[j * n + i] = dist;
+            }
+        }
+    }
+
+    return matrix;
+}
+
+long *initialize_result(int n) {
+    long *result = malloc(sizeof(long) * n*n);
+
+    for (int i = 0; i < n; i++) {
+        for (int j = 0; j < n; j++) {
+            if (i == j) {
+                result[i * n + j] = 0;
+            } else {
+                result[i * n + j] = INF;
+            }
+        }
+    }
+
+    return result;
+}
\ No newline at end of file