Cod sursa(job #168701)

Utilizator pheon23mce mec ecm pheon23 Data 31 martie 2008 18:57:45
Problema Salvare Scor 65
Compilator c Status done
Runda Arhiva de probleme Marime 4.61 kb
//	MORARU CATALIN
//	325CA
//	Tema1 - PA


#define MAX	100000

#include <stdlib.h>
#include <stdio.h>


#define FIN	"salvare.in"
#define FOUT	"salvare.out"

int **vecin;
int *solutie;
int n,k;

/*
	citire date din fisier
*/

void printVec(){
	int i,l;
	for(i=1; i<=n; i++)
	{
		fprintf(stderr,"%d - %d - ",i,vecin[i][0]);
		for(l=1; l<= vecin[i][0]; l++)
			fprintf(stderr,"%d ",vecin[i][l]);
		fprintf(stderr,"\n");
	}
}


void load(){
	int i,a=0,b=0;
	
	FILE *in = fopen(FIN,"rt");
	if(in == NULL)
		fprintf(stderr,"Eroare deshidere fisier intrare");
	fscanf(in,"%d\n",&n);
	fscanf(in,"%d\n",&k);
	
	vecin	= (int**) malloc ((n+1)*sizeof(int*));
	solutie	= (int*)  malloc ((n+1)*sizeof(int));

	for(i=0; i<=n; i++)
	{
		vecin[i] = (int*) calloc ((n+1),sizeof(int));
		vecin[i][0] = 0;
	}

	for(i=1; i<n; i++)
	{
		fscanf(in,"%d %d",&a,&b);

		vecin[a][0]++;
		vecin[a][vecin[a][0]] = b;

		vecin[b][0]++;
		vecin[b][vecin[b][0]] = a;
	}
	fclose(in);
		if(k==n){
		FILE *out = fopen(FOUT,"wt");
		fprintf(out,"0\n");
		for(i=1; i<=n; i++)
			fprintf(out,"%d ",i);
		fclose(out);
		exit(0);
	}
	return ;
}

int cerereDistanta(int c, int cnod, int d){

	if(cnod < 0)
		return c;
	
	if(cnod == 2*d + 1)
		return cnod;

	if (c<=d)
	//cerere normala
	{
		if (c<cnod)
			return c;
		else
			return cnod;
	}
	else
	{
		/*
		if ((2*d + 1 - c + cnod) < d) 
			return c;
		else
			return cnod;
		*/
	}
	return c;
}

int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}


int acoperire(int d){
	int *viz	= (int*)calloc((n+1),sizeof(int));
	int *dist	= (int*)calloc((n+1),sizeof(int));
	int *coada	= (int*)calloc((n+1),sizeof(int));
	int *sol	= (int*)calloc((n+1),sizeof(int));
	int *grad	= (int*)calloc((n+1),sizeof(int));
	int nod;

	int i,prim = 1,ultim = 0;

//	fprintf(stderr," --  d = %d -- \n",d);
	
	sol[0] = 0;
	for(i = 1; i<=n; i++)
	{
		grad[i] = vecin[i][0];
		dist[i] = -1;
		if(grad[i] == 1){
			++ultim;
			coada[ultim] = i;
			dist[i] = d;
		}
		sol[i] = 0;
	}
	viz[0] = 1;
	int vec;
	int mijlocArbore = 0;	

	while(prim<=ultim)
	{
		//il scot din coada
		nod = coada[prim];
		if(prim==ultim)
			mijlocArbore = nod;
		++prim;
		
//		fprintf(stderr,"%d  p=%d  u=%d\n",nod,prim,ultim);
		
	
		//il vizitez
		viz[nod] = 1; 
		++viz[0];
		
		for(i=1; i<=vecin[nod][0]; i++)
		{
			vec = vecin[nod][i];	
			if(viz[vec] == 0)
			{
				grad[vec]--;
				
				dist[vec] = cerereDistanta(dist[nod]-1,dist[vec], d);
				if(dist[vec] == 0)
				{
					sol[0]++;
					sol[sol[0]] = vec;
					dist[vec] = 2*d + 1;
				}
				
				// daca are grad = 1 il pun in coada
				if(grad[vec] == 1)
				{
					++ultim;
					coada[ultim] = vec;
				}
			}
		}
/*
	fprintf(stderr,"\n Coada ");	
	for(i=prim;i<=ultim;i++)fprintf(stderr,"%d ",coada[i]);fprintf(stderr,"\n");
	fprintf(stderr,"\nDist  ");
	for(i=1; i<=n; i++)fprintf(stderr,"%d ",dist[i]);
	fprintf(stderr,"\n");	
*/
	}

	if (sol[0]> 0 && (dist[mijlocArbore]>0) && (dist[mijlocArbore] <= d))
	{
		sol[0]++;
		sol[sol[0]] = mijlocArbore;
	}
	
	//fprintf(stderr,"%d %d",sol[0],viz[0]);
	if(sol[0] == 0 && (viz[0]==(n+1)))
	{
	// distanta e suficient de mare incat sa fie nevoie de un singur nod
	// plast in mijloc
		sol[0] = 1;
		sol[1] = mijlocArbore;
		
	}
	
	
	free(viz);
	free(coada);
/*
	for(i=1;i<=sol[0]; i++)
	{
		fprintf(stderr," = %d =",sol[i]);
	}
*/
	if(sol[0]<=k && sol[0]>0)
	{
	//fprintf(stderr,"alta solutie %d, %d\n",d,sol[0]);
	for (i=0; i<=n; i++) solutie[i]=0;
		//fprintf(stderr,"\n");
		//salvez solutia 
		//solutie[0] = sol[0];
		for(i = 0; i<=sol[0]; i++)
		{
			solutie[i] = sol[i];
		//	fprintf(stderr,"%d ",solutie[i]);
		}
//		fprintf(stderr,"\n");
		return 1;
	}
	else 
		return 0;

}

void print(FILE *out, int d){
	if(out == NULL)
		return;
	int i;

	fprintf(out,"%d\n",d);

	if (solutie[0] < k){
		int *viz;
		viz = (int*)calloc((n+1),sizeof(int));

		for(i=1; i<=solutie[0]; i++)
			viz[solutie[i]]=1;

		for(i=1; i<=n; i++)
		{
			if(viz[i]==0)
			{
				++solutie[0];
				viz[i]=1;
				solutie[solutie[0]]=i;
			}				
			if(solutie[0]==k) break;
		}
	}

	solutie[0]=0;
	qsort(solutie,k+1,sizeof(int),compare);

	for(i=1; i<=k; i++)
	{
		fprintf(out,"%d ",solutie[i]);
	}
	return;
}


int main(){
	load();
	//printVec();
	//int i;

	/*
		cautare binara
	*/
	int min = 1;
	int max = n;
	int mijloc = 0;
	int distanta = -1;
	
	while(min<max)
	{
		//fprintf(stderr,"%d %d\n",min,max);
		mijloc = (int)((max + min) /2);
		//fprintf(stderr,"++++  %d ++++++++ \n",mijloc);

		if(acoperire(mijloc) == 1)
		{
			max = mijloc ;
			distanta = mijloc;
		}
		else
		{
			min = mijloc+1 ;
		}	
	}
	
//	acoperire(3);
//	distanta = 3;
	//print(stderr,distanta);
	print(fopen(FOUT,"wt"),distanta);

	fprintf(stderr,"\n");
	return 0;
}