Cod sursa(job #92654)

Utilizator fireatmyselfBogdan-Alexandru Stoica fireatmyself Data 16 octombrie 2007 10:47:01
Problema Salvare Scor 65
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <cstdio>
#include <vector>

using namespace std;

#define NMAX 100100
#define MIN(a,b) (((a)<(b))?(a):(b))
#define pb push_back

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

void dfs(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;
                dfs(A[i][j]);
            }
}

void _try()
{
        int i, k, j, n;

        for (k = 0; k < nq; k++)
        {
                i = Q[k]; n = A[i].size();

                for (j = 0; j < n; j++)
                    V[i] = MIN(V[i], V[ A[i][j] ]-C[i][j]*B[i]);
                if (V[i]<=0&&i>0)
                {
                        X[i] = 1;
                        V[i] = 1+(md<<1);
                        MinK++;
                }
                G[ tata[i] ]--;
                if (G[ tata[i] ]==1) Q[nq++] = tata[i];
        }
}

int main()
{
        int i, j, k, nf=0, 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);
                G[i]++; G[j]++;
        }

        for (i = 1; i <= N; i++) g[i] = G[i];
        dfs(1);
        G[0] = BIG;
        for (i = 1; i <= N; i++)
            if (G[i]==1) Fr[nf++] = i;

        md = BIG/2;
        for (lo = 1, hi = BIG; lo <= hi; md = (lo+hi)>>1)
        {
                for (i = 1; i <= N; i++) V[i] = ((BIG+1)<<1), X[i] = 0, G[i] = g[i];
                for (i = nq = 0; i < nf; i++)
                    Q[nq++] = Fr[i], V[ Fr[i] ] = md;
                MinK = 0;
                _try();
                if (MinK <= K) hi = md-1, Cmin = md;
                else lo = md+1;
        }

        md = Cmin;
        for (i = 1; i <= N; i++) V[i] = BIG, X[i] = 0, G[i] = g[i];
        for (i = nq = 0; i < nf; i++)
            Q[nq++] = Fr[i], V[ Fr[i] ] = md;
        MinK = 0;
        _try();

        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;
        
}