Cod sursa(job #279614)

Utilizator stocarulCosmin-Mihai Tutunaru stocarul Data 12 martie 2009 21:35:11
Problema Radiatie Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 4.17 kb
#include<stdio.h>
#define infile "radiatie.in"
#define outfile "radiatie.out"
#define nmax 15*1001
#define mmax 30*1001
struct lista
	{
	int n,p; //nodul si pozitia
	int c; //costul
	} l[mmax]; //lista arborelui
struct muchie
	{
	int x,y; //leaga nodul x cu nodul t
	int c; //costul
	} m[mmax]; //muchiile grafului
struct nod
	{
	int c; //componenta conexa din care face parte (cand facem kruskal), respectiv costul de la tata catre el cand raspunde-m la query-uri
	int t; //tatal nodului (in arbore)
	int h; //inaltimea la care se afla nodul in arbore (varful arborelui va fi nodul 1)
	int p; //pozitia din lista
	} n[nmax]; //nodurile
int nrl,nrm,nrn; //numarul pentru fiecare structura
int k; //numarul de intrebari

void add(int m, int x, int y, int c)
	{ //adauga arcul (x,y) cu costul c
	l[m].n=y; l[m].c=c; l[m].p=n[x].p; n[x].p=m;
	}

void citire()
	{
	int i;
	scanf("%d %d %d\n",&nrn,&nrm,&k);
	for(i=1;i<=nrm;i++) //citim fiecare muchie
		scanf("%d %d %d\n",&m[i].x,&m[i].y,&m[i].c); //muchia [x,y] cu costul c
	}

int divide(int p, int q)
	{
	struct muchie x=m[p]; //muchia ce trebuie plasata corect
	while(p<q)
		{
		while(p<q&&m[q].c>=x.c) q--; //cele din dreapta au costul mai mare
		m[p]=m[q];
		while(p<q&&m[p].c<=x.c) p++; //cele din stanga au costul mai mic
		m[q]=m[p];
		}
	m[p]=x; //il plasam corect
	return p; //ii returnam pozitia
	}

void qsort(int p, int q)
	{
	int m=divide(p,q); //il plasam corect pe p
	if(p<m-1) qsort(p,m-1); //partea stanga
	if(m+1<q) qsort(m+1,q); //partea dreapta
	}

void initializare()
	{
	int i;
	for(i=1;i<=nrn;i++) n[i].c=i; //initil fiecare nod e singur in componenta conexa
	}

void dfs(int x, int y)
	{ //face o parcurgere din nodul x, si pune toate nodurile in componenta y
	int p;
	n[x].c=y;
	for(p=n[x].p;p;p=l[p].p) //trecem la toti copii lui x
		if(n[l[p].n].c!=y) //daca nu se afla in componenta y
			dfs(l[p].n,y); //trebuie sa parcurgem
	}

void kruskal()
	{ //construim arborele partial de cost minim
	int i=1; //prima muchie nefolosita
	struct muchie x;
	while((nrl/2)<nrn-1) //trebuie sa avem in lista N-1 muchii
		{
		x=m[i++]; //muchia pe care o putem folosi
		if(n[x.x].c!=n[x.y].c) //daca muchia asta leaga doua puncte din componente conexe diferite
			{
			if(n[x.x].c<n[x.y].c)
				dfs(x.y,n[x.x].c); //uneste cele doua componente conexe in componenta nodului x
			else dfs(x.x,n[x.y].c); //uneste cele doua componente conexe in componenta nodului y
			add(++nrl,x.x,x.y,x.c); //adaugam arcul (x,y) de cost c
			add(++nrl,x.y,x.x,x.c); //adaugam arcum (y,x) de cost c
			}
		}
	}

int inaltime(int x, int y, int c)
	{ //calculam intaltimea nodului x, care il are pe tata pe y, cu muchie de cost c
	int p,k=0;
	n[x].t=y; //ii salvam tatal
	n[x].c=c; //salvam costul
	for(p=n[x].p;p;p=l[p].p) //trecem pe la toti copii
		if(l[p].n!=y) //daca nu este insa-si tatal
			{
			k=inaltime(l[p].n,x,l[p].c); //aflam inaltimea acestui nod
			if(n[x].h<=k) n[x].h=k+1; //avem o intaltime mai mare
			}
	if(k==0) n[x].h=1; //daca nu are inaltime sub :P (adica nu are fii)
	return n[x].h; //returnam inaltimea
	}

int query(int x, int y)
	{
	int m=0; //aici vom calcula lungimea maxima
	while(x!=y)
		{ //cat timp nu am ajuns intr-un stramos comun
		if(n[x].h<n[y].h) //x are inaltimea mai mica....trebuie sa urce ;))
			{
			if(m<n[x].c) m=n[x].c; //avem cost mai mare
			x=n[x].t; //ne ducem la tata;)
			}
		else //y are inaltimea mai mica...trebuie sa urce;))
			{
			if(m<n[y].c) m=n[y].c; //avem cost mai mare
			y=n[y].t; //ne ducem la tata
			}
		}
	return m; //returnam valoarea maxima din traseu ;))
	}

int main()
{
int i,x,y;
freopen(infile,"r",stdin);
freopen(outfile,"w",stdout);

citire(); //citim muchiile
//initializare(); //facem padurea de arbori
//qsort(1,nrm); //sortam muchiile
//kruskal(); //construim arborele partial de cost minim
//inaltime(1,0,0); //calculam inaltimile nodurilor in arbore (considerand nodul 1 tata)
for(i=1;i<=k;i++)
	{
	scanf("%d %d\n",&x,&y); //punctele intre care trebuie calculata muchia ;))
	//printf("%d\n",query(x,y)); //calculam si afisem lungimea muchiei maxime :P
	}

fclose(stdin);
fclose(stdout);
return 0;
}