Cod sursa(job #755575)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 6 iunie 2012 13:16:14
Problema Salvare Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.38 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>

#define NMax 1005
#define LogMax 11

using namespace std;

typedef vector <int> :: iterator vii;

vector <int> T[NMax], Node, SC;
int N, M, Level[NMax], A[LogMax][NMax], Log[NMax], V[NMax], S;

inline bool Compare (const int &a, const int &b)
{
    return Level[a]>Level[b];
}

inline void DFS (int X, int F)
{
    Level[X]=Level[F]+1; A[0][X]=F;
    for (vii Y=T[X].begin (); Y!=T[X].end (); ++Y)
    {
        if (*Y!=F) DFS (*Y, X);
    }
}

void BuildLog ()
{
    for (int i=2; i<=N; ++i) Log[i]=Log[i/2]+1;
}

void BuildA ()
{
    BuildLog ();
    for (int i=1; i<=Log[N]; ++i)
    {
        for (int X=1; X<=N; ++X)
        {
            A[i][X]=A[i-1][A[i-1][X]];
        }
    }
}

inline int FindA (int X, int K)
{
    int Y=X;
    for (int Step=Log[N]; Step>=0; --Step)
    {
        if ((1<<Step)<=K) K-=(1<<Step), Y=A[Step][Y];
    }
    if (!Y) Y=1;
    return Y;
}

inline void MarkDFS (int X, int K)
{
    if (!K) return;
    V[X]=K;
    for (vii Y=T[X].begin (); Y!=T[X].end (); ++Y)
    {
        if (K-1>V[*Y]) MarkDFS (*Y, K-1);
    }
}

inline bool Possible (int K)
{
    memset (V, 0, sizeof (V));
    vector <int> Center;
    for (vii X=Node.begin (); X!=Node.end (); ++X)
    {
        if (!V[*X]) Center.push_back (FindA (*X, K)), MarkDFS (FindA (*X, K), K+1);
        if ((int)Center.size ()>M) return false;
    }
    S=K; SC=Center;
    return true;
}

void BSearch ()
{
    int L=0, R=N/M+1;
    while (L<=R)
    {
        int Mid=(L+R)/2;
        if (Possible (Mid)) R=Mid-1;
        else L=Mid+1;
    }
}

void Solve ()
{
    DFS (1, 0); Level[0]=-N;
    sort (Node.begin (), Node.end (), Compare);
    BuildA ();
    BSearch ();
}

void Read ()
{
    freopen ("salvare.in", "r", stdin);
    scanf ("%d\n%d", &N, &M);
    for (int X=1; X<=N; ++X) Node.push_back (X);
    for (int i=1; i<N; ++i)
    {
        int X, Y; scanf ("%d %d", &X, &Y);
        T[X].push_back (Y); T[Y].push_back (X);
    }
}

void Print ()
{
    freopen ("salvare.out", "w", stdout);
    printf ("%d\n", S);
    sort (SC.begin (), SC.end ());
    for (vii X=SC.begin (); X!=SC.end (); ++X)
    {
        printf ("%d ", *X);
    }
    printf ("\n");
}

int main ()
{
    Read ();
    Solve ();
    Print ();
    return 0;
}