Cod sursa(job #250695)

Utilizator willliIonel Bratianu willli Data 31 ianuarie 2009 16:03:55
Problema Sortare topologica Scor 80
Compilator c Status done
Runda Arhiva educationala Marime 3.03 kb
#include <stdio.h>
#include <stdlib.h>
#define MAX 50000

struct edge
{
	long int value;
	struct edge *next;
};

struct node
{
	int tail_edge;
	struct edge *first, *last;
};

struct edge *head = NULL;
struct edge *tail = NULL;
struct node graph[MAX];
long int sorted_graph[MAX];
long int n, si = 0; //number of nodes from graph;

//add a new edge to graph
void add_edge(long int x, long int y)
{	
	//create a new node
	struct edge *new_edge;	
	if ((new_edge = (struct edge *)malloc(sizeof(struct edge))) == NULL)
	{
		printf("Not enoug memory\n");
		exit(-1);
	}	
	new_edge->value = y;
	new_edge->next = NULL;
	//add a new tail edge
	graph[y].tail_edge++;
	
	if (graph[x].first == NULL)
	{
		//this node hasn't any edge create first edge
		graph[x].first = new_edge;
		graph[x].last = new_edge;
	}
	else
	{
		//add last node to the list
		graph[x].last->next = new_edge;
		graph[x].last = new_edge;
	}
}

//read the graph from input file
void read_file()
{
	FILE *fin;
	long int x, y, m, i;
	
	if ((fin = fopen("sortaret.in", "r")) == NULL)
	{
		printf("Eroare \n");
		exit(-1);
	}
	//read the two nodes
	fscanf(fin, "%ld%ld", &n, &m);
	for (i = 0; i < n; i++)
	{		
		graph[i].tail_edge = 0;
		graph[i].first = NULL;
		graph[i].last = NULL;
	}
	for (i = 0; i < m; i++)
	{
		fscanf(fin, "%ld%ld", &x, &y);
		//add a new node in graph
		add_edge(x - 1, y - 1);
		//printf("Edge %ld %ld\n", x - 1, y - 1);
	}	
	fclose(fin);	
}


//add a new node to queue
void add_queue(long int i)
{
	//create a new node
	struct edge *new_edge;	
	if ((new_edge = (struct edge *)malloc(sizeof(struct edge))) == NULL)
	{
		printf("Not enoug memory\n");
		exit(-1);
	}	
	new_edge->value = i;
	new_edge->next = NULL;	
	if (head == NULL)
	{
		head = new_edge;
		tail = head;
	}
	else
	{
		tail->next = new_edge;
		tail = new_edge;
	}
}

//add the unrefered nodes to the queue
void add_unrefered_nodes()
{
	long int i;
	for (i = 0; i < n; i++)
	{
		if (graph[i].tail_edge == 0)
		{
			//if the node is not refered it is added to the queue
			add_queue(i);
			//printf("Add a new unrefered node %ld\n", i);
		}
	}
}

void df(long int node)
{
	struct edge *t, *t1;
	sorted_graph[si] = node;
	si++;
	t = graph[node].first;	
	while (t != NULL)
	{
		graph[t->value].tail_edge--;
		if (graph[t->value].tail_edge == 0)
		{
			//printf("Adding %ld\n", t->value);
			add_queue(t->value);
			df(t->value);
		}
		t1 = t;
		t = t->next;
		free(t1);
	}	
	graph[node].first = NULL;
}

//sort graph
void topological_sorting()
{
	struct edge *temp;
	//add the unrefered nodes to the queue
	add_unrefered_nodes();
	//printf("Starting sorting\n");
	while (head != NULL)
	{
		//get the head of queue
		temp = head;		
		//printf("Head = %ld\n", head->value);		
		df(temp->value);				
		head = head->next;
		free(temp);		
	}
}

void write_file()
{
	FILE *fout;
	long int i;
	fout = fopen("sortaret.out", "w");
	for (i = 0; i < n; i++)
		fprintf(fout, "%ld ", sorted_graph[i] + 1);
	fclose(fout);
}

int main()
{	
	//read the file
	read_file();
	
	//sort the graph
	topological_sorting();

	//write the output file
	write_file();
	
	return 0;
}