Cod sursa(job #92268)

Utilizator fireatmyselfBogdan-Alexandru Stoica fireatmyself Data 14 octombrie 2007 19:52:22
Problema Salvare Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.38 kb
#include <cstdio>
#include <vector>

using namespace std;

#define NMAX 100100
#define MAX(a,b) (((a)>(b))?(a):(b))
#define pb push_back

vector<long long> C[NMAX];
vector<int> A[NMAX];
int N, K, MinK, F[NMAX], X[NMAX], tata[NMAX];
long long BIG, Cmin, lo, hi, md, B[NMAX], S[NMAX], V[NMAX];

void parent(int i)
{
        int j, n = A[i].size();

        F[i] = 1;
        for (j = 0; j < n; j++)
            if (!F[ A[i][j] ]) {
                 tata[ A[i][j] ] = i;
                 parent(A[i][j]); }
}

void getsum(int i)
{
        int j, n = A[i].size();

        F[i] = 1;
        for (j = 0; j < n; j++)
            if (!F[ A[i][j] ])
               getsum(A[i][j]);

        for (j = 0; j < n; j++)
            if (tata[i] != A[i][j])
               S[i] = MAX(S[i], S[ A[i][j] ]+C[i][j]*B[ A[i][j] ]);
}

void df(int i)
{
        int j, pvmax, n = A[i].size();
        long long vmax;

        if (MinK > K) return;

        F[i] = 1;
        for (j = 0; j < n; j++)
            if (!F[ A[i][j] ]) df(A[i][j]);

        V[i] = 0;
        for (j = 0; j < n; j++)
            if (tata[i] != A[i][j])
               V[i] = MAX(V[i], V[ A[i][j] ]+C[i][j]*B[ A[i][j] ]);

        while (V[i]>md)
        {
                vmax = -1, pvmax = 0;
                for (j = 0; j < n; j++)
                    if (tata[i] != A[i][j])
                       if (vmax < V[ A[i][j] ]) vmax = V[ A[i][j] ], pvmax = j;
                V[ A[i][pvmax] ] = 0;
                V[i] = 0;
                X[ A[i][pvmax] ] = 1;
                for (j = 0; j < n; j++)
                    if (tata[i] != A[i][j])
                       if (V[ A[i][j] ]>=0)
                          V[i] = MAX(V[i], V[ A[i][j] ]+C[i][j]*B[ A[i][j] ]);
                MinK++;
                if (MinK > K) break;
        }

        vmax = 0;
        for (j = 0; j < n; j++)
            if (tata[i] != A[i][j])
               if ((1+V[ A[i][j] ])!=V[i])
                  if ((V[ A[i][j] ]+C[i][j])>vmax) vmax = C[i][j]+V[ A[i][j] ];
        if ((V[i]+vmax)>md)
           V[i] = 0, X[i] = 1, MinK++;
}

int main()
{
        int i, j, k, t;
        long long a = 1000000000, b = 1000000;

        BIG = a*b;

        freopen("salvare.in", "r", stdin);
        freopen("salvare.out", "w", stdout);
        
        scanf("%d%d", &N, &K);
        for (t = 1; t <= N; t++) B[t] = 1;
        for (t = 1; t < N; t++)
        {
                scanf("%d%d", &i, &j); k = 1;
                A[i].pb(j); A[j].pb(i); C[i].pb(k); C[j].pb(k);
        }

        parent(1);
        for (i = 1; i <= N; i++) F[i] = 0;
        getsum(1);

        md = BIG/2;
        for (lo = 0, hi = BIG; lo <= hi; md = (lo+hi)>>1)
        {
                for (i = 1; i <= N; i++) {
                    V[i] = S[i];
                    F[i] = X[i] = 0; }
                MinK = 0;
                df(1);
                if (MinK <= K) hi = md-1, Cmin = md;
                else lo = md+1;
        }

        md = Cmin;
        for (i = 1; i <= N; i++) {
            V[i] = S[i];
            F[i] = X[i] = 0; }
        MinK = 0;
        df(1);

        for (i = 1; i <= N && MinK < K; i++)
            if (!X[i]) X[i] = 1, MinK++;

        printf("%lld\n", Cmin);
        for (i = 1; i <= N; i++)
            if (X[i]) printf("%d ", i);
        printf("\n");

        return 0;
        
}