Cod sursa(job #168533)

Utilizator Ragnar_LodbrokGrosu Codrut Ragnar_Lodbrok Data 31 martie 2008 16:27:59
Problema Salvare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <stdio.h>

#define NMAX 100001

FILE *fin,*fout;

int N,M;
int grad[NMAX+1];

int *gr[NMAX+1];

int P,dp[NMAX+1];
int coada[NMAX+1],sf_c,i_c,tata[NMAX+1];

struct muc
{int cs,cd;
}muchie[NMAX+1];

inline int minim(int a,int b)
{return ((a>b)?(b):(a));}
inline int maxim(int a,int b)
{return ((a>b)?(a):(b));}


//calculeaza o enumerare a nodurilor arborelui astfel incat pentru orice nod toti fii lui
//sa fie dupa el in vectorul parcurgerii
void fixed_enumeration()
{int i,cv;
 i_c=sf_c=0;
 coada[sf_c++]=0;
 tata[0]=-1;
 for (;i_c<sf_c;i_c++)
    {cv=coada[i_c];
     for (i=0;i<grad[cv];++i)
        if (gr[cv][i] != tata[cv]) {coada[sf_c++]=gr[cv][i];tata[gr[cv][i]]=cv;}
    }
 //assert(sf_c == N);
}

//aseaza greedy punctele de prim ajutor, pornind de la frunze inspre radacina
int greedy(int d)
{int i,j,cv;
 int a,b;
 if (d<0) return 0;
 for (i=N-1;i>=0;--i)
    {cv=coada[i];
     b=2*d+1;a=-1;
     for (j=0;j<grad[cv];++j)
        if (tata[gr[cv][j]]==cv)
           {if (dp[gr[cv][j]]<d) a=maxim(a,dp[gr[cv][j]]);
            else b=minim(b,dp[gr[cv][j]]);
           }
     if (a+2+b-d<=d) dp[cv]=b+1;
     else dp[cv]=a+1;
     if (dp[cv] > 2*d) dp[cv]-=(2*d+1);
    }
 if (dp[cv] < d) dp[cv]=d;          //punem punct de ajutor in radacina daca e cazul 
 P=0;
 for (i=0;i<N;++i) P+=(dp[i] == d);
 return (P<=M);
}

int main()
{
 int i,a,b;
 int k,l;
 fin=fopen("salvare.in","r");
 fscanf(fin,"%d %d",&N,&M);
 /*for (i=0;i<N;++i)
 	{fscanf(fin,"%d",&grad[i]);
	 gr[i]=new int[grad[i]+1];
	 for (j=0;j<grad[i];++j) {fscanf(fin,"%d",&gr[i][j]);--gr[i][j];}
	}*/
 for (i=0;i<N-1;++i)
    {fscanf(fin,"%d %d",&a,&b);
     --a;--b;
     ++grad[a];++grad[b];
     muchie[i].cs=a;muchie[i].cd=b;
    }
 for (i=0;i<N;++i)
    {gr[i]=new int[grad[i]+1];grad[i]=0;}
 for (i=0;i<N-1;++i)
    {a=muchie[i].cs;b=muchie[i].cd;
     gr[a][grad[a]++]=b;
     gr[b][grad[b]++]=a;
    }
 fclose(fin);
 
 fixed_enumeration();
 
 for (l=1;l<=N;l<<=1);
 for (k=-1;l>0;l>>=1)
	if (k+l < N && greedy(k+l) == 0) k+=l;
 
 fout=fopen("salvare.out","w");
 greedy(k+1);
 fprintf(fout,"%d\n",k+1);
 M-=P;
 for (i=0;i<N;++i)
    if (dp[i] == k+1) fprintf(fout,"%d ",i+1);
    else if (M>0) {--M;fprintf(fout,"%d ",i+1);}
 fprintf(fout,"\n");
 fclose(fout);
 return 0;
}