Cod sursa(job #578439)

Utilizator tamas_iuliaTamas Iulia tamas_iulia Data 11 aprilie 2011 12:05:10
Problema Salvare Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
#define Nmax 1002
#define Lgmax 10
#define pb push_back
using namespace std;

vector< int > v[Nmax];
int Str[Lgmax][Nmax];
int Q[Nmax],Niv[Nmax],ind[Nmax],use[Nmax];
int N,K,st,dr;

inline void df(int x){
    vector< int >:: iterator it;
    Niv[x]=Niv[Str[0][x]]+1;
    for(it=v[x].begin(); it!=v[x].end(); ++it)
        if( !Niv[*it] ){
            Str[0][*it]=x;
            df(*it);
        }
}

inline int cmp(int i,int j){ return Niv[i]>Niv[j]; }

inline void precal_stramosi(){
    int i,j;
    for(i=1;i<Lgmax;++i)
        for(j=1;j<=N;++j)
            Str[i][j]=Str[i-1][Str[i-1][j]];
}

inline int find_stramos(int i,int care){
    int j;
    for(j=0; (1<<j) <=care; ) j++;
    j--;

    while( care && j>=0 ){
        while( (1<<j) > care ) j--;
        i=Str[j][i];
        care -= (1<<j);
    }
    if( care ) return 1;
    else return i;
}

inline int dist(int x,int y){
    int p,xx=x,yy=y;
    if( Niv[x]<Niv[y] ) x^=y, y^=x, x^=y;
    for(p=0; (1<<p)<=Niv[x]; ) ++p; --p;

    while( Niv[x] > Niv[y] ){
        while( Niv[x]-(1<<p) < Niv[y] ) p--;
        x=Str[p][x];
    }

    for(p=0; (1<<p)<=Niv[x]; ) ++p; --p;
    for(; p>=0; --p)
        if( Str[p][x] != Str[p][y] )
            x=Str[p][x], y=Str[p][y];

    if( x==y );
    else x=Str[0][x];
    return Niv[xx]-Niv[x]+ Niv[yy]-Niv[x]; // distanta de la fiecare la lca
}

inline int merge(int T){
    int i,j,ii,strii,use1;
    st=1; dr=0; use1=0;

    for(i=1;i<=N;++i){
        ii=ind[i];

        while( Niv[Q[st]] - Niv[ii] > T ) st++;

        for(j=st;j<=dr;++j)
            if( dist(ii,Q[j]) <= T ) break;
        if( j==dr+1 ){
            strii=find_stramos(ii,T);
            if( strii!=1 || (strii==1 && !use1) ){
                Q[++dr]=strii;
                if( strii==1 ) use1=1;
            }

        }
    }
    if( dr<= K ) return 1;
    return 0;
}


int main(){
    int i,j,x,y,l,r,m,ret;
    freopen("salvare.in","r",stdin);
    freopen("salvare.out","w",stdout);
    scanf("%d%d",&N,&K);
    for(i=1;i<N;++i){
        scanf("%d%d",&x,&y);
        v[x].pb(y);
        v[y].pb(x);
    }
    df(1); // agat arb
    precal_stramosi();

    for(i=1;i<=N;++i) ind[i]=i;
    sort(ind+1,ind+N+1,cmp);

    l=0;r=N;
    while(l<=r){
        m=l+(r-l)/2;
        if( merge(m) ) ret=m, r=m-1;
        else l=m+1;
    }

    merge(ret);
    printf("%d\n",ret);
    for(i=1;i<=dr;++i) use[Q[i]]=1;
    for( j=1; dr<K; ){
        while( use[j] ) ++j;
        Q[++dr]=j; use[j]=1;
    }

    sort(Q+1,Q+K+1);
    for(i=1;i<=K;++i) printf("%d ",Q[i]);

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