diff --git a/TP4_q4.c b/TP4_q4.c
new file mode 100644
index 0000000000000000000000000000000000000000..ff99a8ca93b00f5c2ba2e8248abdccd1d4f4c568
--- /dev/null
+++ b/TP4_q4.c
@@ -0,0 +1,376 @@
+#include "./implems.c"
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+void aff_tab(unsigned long *t, int size)
+{
+	for (int i = 0; i < size; i++)
+	{
+		printf("%li ", t[i]);
+	}
+	printf("\n");
+}
+
+// génère un nombre aléatoire sur 4 octets
+unsigned long randlu()
+{
+	unsigned long res = 0;
+	unsigned long tmp1 = rand() & 0x0F;
+	unsigned long tmp2 = rand() & 0x0F;
+	unsigned long tmp3 = rand() & 0x0F;
+	unsigned long tmp4 = rand() & 0x0F;
+
+	tmp2 = tmp2 << 8;
+	tmp3 = tmp3 << 16;
+	tmp4 = tmp4 << 24;
+
+	res = res | tmp1;
+	res = res | tmp2;
+	res = res | tmp3;
+	res = res | tmp4;
+
+	return res;
+}
+
+// génère un nombre aléatoire sur 4 octets entre min et max inclue
+unsigned long randlu_from(unsigned long min, unsigned long max)
+{
+	unsigned long range = (max - min);
+	return min + (randlu() % (range + 1));
+}
+
+void Fisher_Yates(unsigned long *tab, unsigned long size)
+{
+	unsigned long tmp;
+	unsigned long rdm;
+	for (unsigned long i = size - 1; i > 0; i--)
+	{
+		rdm = randlu_from(0, i);
+		tmp = tab[i];
+		tab[i] = tab[rdm];
+		tab[rdm] = tmp;
+	}
+}
+
+void ajuste_label_1(adjlist *g, unsigned long *label, unsigned long *label_count, unsigned long node, unsigned long commu)
+{
+	label[node] = commu;
+	unsigned long size_commu = 1;
+	unsigned long nb = 1;
+	unsigned long best = 0;
+
+	for (unsigned long i = 0; i < g->n; i++)
+	{
+		label_count[i] = 0;
+	}
+
+	for (unsigned long i = g->cd[node]; i < g->cd[node + 1]; i++)
+	{
+		if (label[g->adj[i]] == 0)
+		{
+			label_count[g->adj[i]]++;
+		}
+	}
+
+	int in_progress = 1;
+
+	while (in_progress)
+	{
+		in_progress = 0;
+		nb = 1;
+		best = label_count[0];
+
+		for (unsigned long i = 1; i < g->n; i++)
+		{
+			if (label_count[i] > best)
+			{
+				best = label_count[i];
+				nb = 1;
+			}
+			else if (label_count[i] == best)
+			{
+				nb++;
+			}
+		}
+
+		if (best >= size_commu / 2)
+		{
+			in_progress = 1;
+			unsigned long chosen = randlu_from(1, nb);
+			unsigned long i = 0;
+
+			while (i < g->n && chosen > 0)
+			{
+				if (label_count[i] == best)
+				{
+					chosen--;
+					if (chosen == 0)
+					{
+						label[i] = commu;
+						size_commu++;
+						for (unsigned long j = g->cd[i]; j < g->cd[i + 1]; j++)
+						{
+							if (label[g->adj[j]] == 0)
+							{
+								label_count[g->adj[j]]++;
+							}
+						}
+					}
+				}
+				i++;
+			}
+			if (chosen != 0)
+			{
+				printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n");
+			}
+		}
+	}
+}
+
+int ajuste_label_2(adjlist *g, unsigned long *label, unsigned long *label_count, unsigned long node)
+{
+
+	for (unsigned long i = 0; i < g->n; i++)
+	{
+		label_count[i] = 0;
+	}
+
+	for (unsigned long i = g->cd[node]; i < g->cd[node + 1]; i++)
+	{
+		label_count[label[g->adj[i]]]++;
+	}
+
+	unsigned long best = 0;
+
+	for (unsigned long i = 1; i < g->n; i++)
+	{
+		if (label_count[i] > label_count[best])
+		{
+			best = i;
+		}
+	}
+
+	if (label[node] == best)
+	{
+		return 0;
+	}
+	
+
+	if (label_count[best] > (g->cd[node + 1] - g->cd[node]) / 2)
+	{
+		label[node] = best;
+		return 1;
+	}
+
+	return 0;
+}
+
+unsigned long *label_propagation(adjlist *g)
+{
+	unsigned long *ordre = (unsigned long *)malloc(sizeof(unsigned long) * g->n);
+	unsigned long *label = (unsigned long *)malloc(sizeof(unsigned long) * g->n);
+	unsigned long *label_count = (unsigned long *)malloc(sizeof(unsigned long) * g->n);
+
+	unsigned long nb_commu = 0;
+
+	for (unsigned long i = 0; i < g->n; i++)
+	{
+		ordre[i] = i;
+		label[i] = 0;
+	}
+
+	Fisher_Yates(ordre, g->n);
+	for (unsigned long i = 0; i < g->n; i++)
+	{
+		if (label[i] == 0)
+		{
+			nb_commu++;
+			ajuste_label_1(g, label, label_count, ordre[i], nb_commu);
+		}
+	}
+
+	int in_progress = 1;
+
+	while (in_progress)
+	{
+		in_progress = 0;
+		Fisher_Yates(ordre, g->n);
+		for (unsigned long i = 0; i < g->n; i++)
+		{
+			in_progress = in_progress | ajuste_label_2(g, label, label_count, ordre[i]);
+		}
+	}
+
+	free(ordre);
+	free(label_count);
+	return label;
+}
+
+// -----------------------------------------------------------------------------------------------------------------------------------------
+
+// renvoie le nombre de label et les renommes
+unsigned long simplifie_label(unsigned long *label, unsigned long size)
+{
+	unsigned long c = 0;
+	unsigned long smallest = size;
+	unsigned long in_progress = 1;
+	while (in_progress)
+	{
+		in_progress = 0;
+		smallest = size;
+		for (unsigned long i = 0; i < size; i++)
+		{
+			if (label[i] >= c && label[i] < smallest)
+			{
+				smallest = label[i];
+				in_progress = 1;
+			}
+		}
+		for (unsigned long i = 0; i < size; i++)
+		{
+			if (label[i] == smallest)
+			{
+				label[i] = c;
+			}
+		}
+		c++;
+	}
+	return c - 1;
+}
+
+void output_graphe(adjlist *g, unsigned long *label, char *filename)
+{
+	FILE *ptr;
+	unsigned long tmp_nb_node;
+
+	tmp_nb_node = g->n;
+
+	ptr = fopen(filename, "w");
+
+	//définition des noeuds
+	fprintf(ptr, "graph D {\n");
+	//noeuds
+	for (unsigned long k = 0; k < tmp_nb_node; k++)
+	{
+		fprintf(ptr, "%li [", k);
+		switch (label[k])
+		{
+		case 0:
+			fprintf(ptr, "color=red");
+			break;
+		case 1:
+			fprintf(ptr, "color=blue");
+			break;
+		case 2:
+			fprintf(ptr, "color=green");
+			break;
+		case 3:
+			fprintf(ptr, "color=yellow");
+			break;
+		case 4:
+			fprintf(ptr, "color=black");
+			break;
+		case 5:
+			fprintf(ptr, "color=brown");
+			break;
+		case 6:
+			fprintf(ptr, "color=orange");
+			break;
+		case 7:
+			fprintf(ptr, "color=grey");
+			break;
+		case 8:
+			fprintf(ptr, "color=magenta");
+			break;
+		case 9:
+			fprintf(ptr, "color=aqua");
+			break;
+		case 10:
+			fprintf(ptr, "color=lime");
+			break;
+
+		default:
+			fprintf(ptr, "color=white");
+			break;
+		}
+
+		fprintf(ptr, "]\n");
+	}
+
+	for (unsigned long k = 0; k < tmp_nb_node; k++)
+	{
+		for (unsigned long i = g->cd[k]; i < g->cd[k + 1]; i++)
+		{
+			if (g->adj[i] > k)
+			{
+				fprintf(ptr, "%li -- %li\n", k, g->adj[i]);
+			}
+		}
+	}
+	fprintf(ptr, "}");
+	fclose(ptr);
+	return;
+}
+
+// -----------------------------------------------------------------------------------------------------------------------------------------
+
+int main(int argc, char **argv)
+{
+	if (argc < 2)
+	{
+		printf("un argument est attendu\n");
+		return 1;
+	}
+
+	adjlist *g;
+	time_t t1, t2, t3, t4;
+
+	// PARSING
+	t1 = time(NULL);
+
+	printf("Reading edgelist from file %s\n", argv[1]);
+	g = al_readedgelist(argv[1]);
+	t3 = time(NULL);
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
+	printf("- edge list time = %I64dh%I64dm%I64ds\n", (t3 - t1) / 3600, ((t3 - t1) % 3600) / 60, ((t3 - t1) % 60));
+#else
+	printf("- edge list time = %ldh%ldm%lds\n", (t3 - t1) / 3600, ((t3 - t1) % 3600) / 60, ((t3 - t1) % 60));
+#endif
+
+	printf("Number of nodes: %lu\n", g->n);
+	printf("Number of edges: %lu\n", g->e);
+
+	printf("Building the adjacency list\n");
+	mkadjlist(g);
+
+	t2 = time(NULL);
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
+	printf("- Overall time = %I64dh%I64dm%I64ds\n", (t2 - t1) / 3600, ((t2 - t1) % 3600) / 60, ((t2 - t1) % 60));
+#else
+	printf("- Overall time = %ldh%ldm%lds\n", (t2 - t1) / 3600, ((t2 - t1) % 3600) / 60, ((t2 - t1) % 60));
+#endif
+
+	// srand(time(NULL));
+
+	unsigned long *res = label_propagation(g);
+
+	t4 = time(NULL);
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
+	printf("- label_propagation time = %I64dh%I64dm%I64ds\n", (t4 - t2) / 3600, ((t4 - t2) % 3600) / 60, ((t4 - t2) % 60));
+#else
+	printf("- label_propagation time = %ldh%ldm%lds\n", (t4 - t2) / 3600, ((t4 - t2) % 3600) / 60, ((t4 - t2) % 60));
+#endif
+
+	unsigned long nb = simplifie_label(res, g->n);
+	printf("%li label different\n", nb);
+	output_graphe(g, res, "toto.dot");
+
+	printf("run {dot -Tpng -o out.png toto.dot} pour avoir une visualisation de la solution\n");
+
+	free(res);
+	free_adjlist(g);
+	return 0;
+}