Cod sursa(job #913711)

Utilizator paul_gabryelPaul Buda paul_gabryel Data 13 martie 2013 18:43:49
Problema Salvare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

ifstream in ("salvare.in");
ofstream out ("salvare.out");

const int N = 1001;

int n,k,ND[N],L[11][N],SOL,log[N];
vector<int> G[N],V,SP;
bool UZ[N];

void READ ()
{

    in>>n>>k;

    for( int x,y,i=1 ; i < n ; ++i )
    {
        in>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);
    }

}

int T (int nod,int D)
{
    for( int i=log[n] ; i >= 0 ; --i )
        if( (1<<i) <= D )
        {
            D-=(1<<i);
            nod=L[i][nod];
        }
    return nod;
}

void DF (int nod,int D)
{

    if( !D )
        return;

    V[nod]=D;

    for( vector<int>::iterator it=G[nod].begin() ; it < G[nod].end() ; ++it )
        if( D > V[*it]+1 )
            DF ( *it , D-1 );

}

bool OK (int D)
{

    V.assign(n+1,0);
    vector<int> S;

    for( int i=1 ; i <= n ; ++i )
    {

        if( !V[ND[i]] )
        {
            int LC=T(ND[i],D);
            S.push_back(LC);
            DF(LC,D+1);
        }

        if( S.size() > k )
            return 0;

    }

    SP=S;

    return 1;

}

void SEARCH (int ft,int bk)
{

    if( ft == bk )
    {
        if( ft < SOL && OK(ft) )
            SOL=ft;
        return;
    }

    int mid=(ft+bk)>>1;

    if( OK(mid) )
    {
        SOL=mid;
        SEARCH ( ft , mid );
        return ;
    }

    SEARCH ( mid+1  , bk );


}

void SOLVE ()
{

    queue<int> Q;
    int m=n;
    L[0][1]=1;
    for( Q.push(1) ; Q.size() ; Q.pop() )
    {
        int nod=Q.front();
        ND[m]=nod;
        --m;
        for( vector<int>::iterator it=G[nod].begin() ; it < G[nod].end() ; ++it )
            if( !L[0][*it] )
            {
                L[0][*it]=nod;
                Q.push(*it);
            }
    }

    for( int i=2 ; i <= n ; ++i )
        log[i]=log[i>>1]+1;

    for( int i=1 ; i <= log[n] ; ++i )
        for( int j=1 ; j <=n ; ++j )
            L[i][j]=L[i-1][L[i-1][j]];

    SEARCH ( 0 , n/k+1 );

    for( vector<int>::iterator it=SP.begin() ; it < SP.end() ; ++it )
        UZ[*it]=1;

    k-=SP.size();

    for( int i=1 ; i <= n && k ; ++i  )
        if( !UZ[i] )
        {
            SP.push_back(i);
            --k;
        }
    sort( SP.begin() , SP.end() );

}

void PRINT ()
{

    out<<SOL<<'\n';

    for( vector<int>::iterator it=SP.begin() ; it < SP.end() ; ++it )
        out<<*it<<' ';

}

int main ()
{

    READ ();
    SOLVE ();
    PRINT ();

    return 0;

}