Cod sursa(job #2157367)

Utilizator arcoC. Nicolae arco Data 9 martie 2018 16:17:03
Problema Diametrul unui arbore Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 2.82 kb
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

typedef unsigned int uint;

// TEORIE:
// Diametrul unui arbore este numarul de noduri de pe lantul cel mai lung care
// leaga 2 frunze dintr-un arbore.
// Pentru a determina in mod eficient acest mod procedam astfel:
//  Parcurgem arborele folosind DFS sau BFS pornind de la un varf oarecare
//  a arborelui, apoi mai parcurgem odata graficul pornind de la ultimul nod
//  la care am ajuns in urma ultimei parcurgeri.
//  Complexitate: O(n)

struct node
{
	uint payload; // node's key value
	uint *lista_adiacenta;
	uint size;
};

void add_edge(struct node *dx, struct node *px);
bool linear_search(uint *vector, uint size, uint key);

uint max = 0;
int ch = 0;
uint last = 0;
void dfs(uint *viz, struct node *adia, uint n, uint p);

int main(void)
{
	FILE *in =  fopen("darb.in", "r");
	FILE *out = fopen("darb.out", "w");

	if(in != NULL && out != NULL)
	{
		uint n;
		fscanf(in, "%u%*c", &n);
		struct node *varfuri = calloc(n + 1, sizeof(struct node));
		uint viz[100000] = {0};
		if(varfuri != NULL)
		{
			while(!feof(in))
			{
				uint a, b;
				fscanf(in, "%u%*c%u%*c", &a, &b);
				if(!viz[a])
				{
					struct node kp;
					kp.payload = a;
					kp.lista_adiacenta = NULL;
					kp.size = 0;
					varfuri[a] = kp;
				}
				if(!viz[b])
				{
					struct node kp;
					kp.payload = b;
					kp.lista_adiacenta = NULL;
					kp.size = 0;	
					varfuri[b] = kp;
				}
				viz[a]++;
				viz[b]++;
				add_edge(&varfuri[a], &varfuri[b]);
			}

			uint v2[100000] = {0};
			dfs(v2, varfuri, n, 1);
			ch = 0;
			max = 0;
			memset(v2, 0, sizeof(uint) * 100000);
			dfs(v2, varfuri, n, last);
			fprintf(out, "%u\n", max);

			free(varfuri);
		}
		else
		{
			printf("error\n");
		}

		fclose(in);
		fclose(out);
	}
	else
	{
		printf("file error\n");
	}

	return 0;
}

void dfs(uint *viz, struct node *adia, uint n, uint p)
{
	ch++;
	if(ch > max)
	{
		last = p;
		max = ch;
	}
	viz[p] = 1;
	uint i = 0;
	for(; i < adia[p].size; i++)
	{
		if(!viz[adia[p].lista_adiacenta[i]])
		{
			dfs(viz, adia, n, adia[p].lista_adiacenta[i]);
		}
	}
	viz[p] = 0;
	ch--;
}

bool linear_search(uint *vector, uint size, uint key)
{
	uint i = 0;
	for(; i < size; i++)
	{
		if(vector[i] == key)
		{
			return true;
		}
	}
	return false;
}

void add_edge(struct node *dx, struct node *px)
{
	dx->size++;
	px->size++;
	dx->lista_adiacenta = realloc(dx->lista_adiacenta, sizeof(uint) * dx->size);
	px->lista_adiacenta = realloc(px->lista_adiacenta, sizeof(uint) * px->size);
	if(dx->lista_adiacenta != NULL && px->lista_adiacenta != NULL)
	{
		dx->lista_adiacenta[dx->size - 1] = px->payload;
		px->lista_adiacenta[px->size - 1] = dx->payload;
	}
	else
	{
		printf("error\n");
	}
}