Cod sursa(job #463312)

Utilizator plastikDan George Filimon plastik Data 14 iunie 2010 22:48:51
Problema Componente tare conexe Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 2.33 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
	int **Next, 
	    *numNext,
	    n, m;
} Graph;

typedef struct {
	int post, i;
} PostNode;

inline void initGraph(Graph *G, int n, int m) {
	G->n = n;
	G->m = m;
	G->Next = (int**)calloc(n, sizeof(int*));
	G->numNext = (int*)calloc(n, sizeof(int));
}

void freeGraph(Graph *G) {
	int i;
	for (i = 0; i < G->n; ++ i)
		free(G->Next[i]);
	free(G->Next);
	free(G->numNext);
}

inline void addEdge(Graph *G, int a, int b) {
	G->Next[a] = (int*)realloc(G->Next[a], (G->numNext[a] + 1) * sizeof(int));
	G->Next[a][G->numNext[a] ++] = b;
}

int t;
int *Order, numOrder;
void depthFirstPost(Graph G, int a, int *Used, PostNode *Post) {
	Used[a] = 1;
	int i, next;
	for (i = 0; i < G.numNext[a]; ++ i) {
		next = G.Next[a][i];
		if (!Used[next]) {
			t ++;
			depthFirstPost(G, next, Used, Post);
		}
	}
	Post[a].post = ++ t;
	Post[a].i = a;
	Order[numOrder ++] = a;
}

void depthFirst(Graph G, int a, int label, int *Used) {
	Used[a] = label;
	int i, next;
	for (i = 0; i < G.numNext[a]; ++ i) {
		next = G.Next[a][i];
		if (!Used[next])
			depthFirst(G, next, label, Used);
	}
}

int postCmp(const void *a, const void *b) {
	return ( (PostNode*)b )->post - ( (PostNode*)a )->post;
}

int main() {
	FILE *in = fopen("ctc.in", "r");
	freopen("ctc.out", "w", stdout);

	int n, m, i, a, b;
	fscanf(in, "%d%d", &n, &m);
	
	Graph G, GT;
	initGraph(&G, n, m), initGraph(&GT, n, m);
	for (i = 0; i < m; ++ i) {
		fscanf(in, "%d%d", &a, &b);
		-- a, --b;
		addEdge(&G, a, b);
		addEdge(&GT, b, a);
	}
	fclose(in);

	int *Used = (int*)calloc(n, sizeof(int));
	PostNode *Post = (PostNode*)calloc(n, sizeof(PostNode));

	Order = (int*)calloc(n, sizeof(int));
	numOrder = 0;

	t = 1;
	for (i = 0; i < n; ++ i) {
		if (!Used[i])
			depthFirstPost(G, i, Used, Post);
	}
	//qsort(Post, n, sizeof(PostNode), postCmp);

	/*for (i = n - 1; i >= 0; -- i)
		printf("(%d %d) ", Post[Order[i]].i, Post[Order[i]].post);
	printf("\n");*/

	memset(Used, 0, n * sizeof(int));
	int label, j;
	for (i = 0, label = 1; i < n; ++ i)
		if (!Used[Post[i].i])
			depthFirst(GT, Post[i].i, label ++, Used);

	printf("%d\n", label - 1);
	for (i = 1; i < label; ++ i) {
		for (j = 0; j < n; ++ j)
			if (Used[j] == i)
				printf("%d ", j + 1);
		printf("\n");
	}

	free(Order);
	free(Post);
	free(Used);

	freeGraph(&G);
	freeGraph(&GT);
	return 0;
}