Cod sursa(job #646117)

Utilizator belginstirbuasdf asdf belginstirbu Data 10 decembrie 2011 21:40:01
Problema Paduri de multimi disjuncte Scor 40
Compilator c Status done
Runda Arhiva educationala Marime 1.87 kb
#include <stdio.h>
#include <stdlib.h>

struct NODE
{
	unsigned short height;
	unsigned int id;
	struct NODE *parent;
	struct NODE **list;
} *mult;

unsigned int N, M;

void initMem(unsigned int a)
{
	unsigned int i;
	if(!mult[a].list)
	{
		mult[a].list = (struct NODE**)malloc(sizeof(struct NODE*) * (N + 1));
		for(i = 1; i <= N; ++i)
			mult[a].list[i] = NULL;
	}
}

struct NODE *findRoot(unsigned int x)
{
	struct NODE *temp = &mult[x];
	struct NODE *root;
	struct NODE *tempParent;
	
	while(temp -> parent)
		temp = temp -> parent;
	root = temp;
	
	temp = &mult[x];
	
	while(temp != root)
	{
		tempParent = temp -> parent;
		temp -> parent = root;
		root -> list[temp -> id] = temp;
		
		temp = tempParent;
	}
	
	return root;
}

void op1(unsigned int x, unsigned int y)
{
	struct NODE *rx = findRoot(x);
	struct NODE *ry = findRoot(y);
	
	if(rx -> height > ry -> height)
	{
		rx -> list[ry -> id] = ry;
		ry -> parent = rx;
	}
	else if(rx -> height < ry -> height)
	{
		ry -> list[rx -> id] = rx;
		rx -> parent = ry;
	}
	else
	{
		++(rx -> height);
		rx -> list[ry -> id] = ry;
		ry -> parent = rx;
	}
}

short op2(unsigned int x, unsigned int y)
{
	struct NODE *rx = findRoot(x);
	struct NODE *ry = findRoot(y);
	return rx == ry;
}

int main()
{
	unsigned int op, x, y, i;
	freopen("disjoint.in", "r", stdin);
	freopen("disjoint.out", "w", stdout);
	
	scanf("%u %u", &N, &M);
	mult = (struct NODE*)malloc(sizeof(struct NODE) * (N + 1));
	
	for(i = 1; i <= N; ++i)
	{
		mult[i].parent = NULL;
		mult[i].list = NULL;
		mult[i].height = 1;
		mult[i].id = i;
	}
	
	while(M--)
	{
		scanf("%u %u %u", &op, &x, &y);
		
		initMem(x);
		initMem(y);
		
		switch(op)
		{
		case 1:
			op1(x, y);
			break;
		case 2:
			if(op2(x, y))
				puts("DA");
			else
				puts("NU");
			break;
		}
	}
	
	return 0;
}