Cod sursa(job #552214)

Utilizator vladiiIonescu Vlad vladii Data 11 martie 2011 20:44:04
Problema Salvare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.13 kb
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
#define maxn 1024
#define pb push_back
#define mkp make_pair

int N, K, sol;
int aj[maxn], viz[maxn], lev[maxn], tt[maxn], dst[maxn][maxn], used[maxn];
vector<pair<int, int> > V;
vector<int> G[maxn], aux;

int cmp(pair<int, int> a, pair<int, int> b) {
    return a.first > b.first;
}

void DFS(int nod, int lvl) {
    viz[nod] = 1; lev[nod] = lvl;
    for(int i=0; i<G[nod].size(); i++) {
         if(!viz[ G[nod][i] ]) {
              tt[ G[nod][i] ] = nod;
              DFS( G[nod][i], lvl + 1 );
         }
    }
}

void BFS(int nod) {
    queue<int> Q;
    memset(viz, 0, sizeof(viz));
    dst[nod][nod] = 0;
    Q.push(nod); viz[nod] = 1;
    while(!Q.empty()) {
         int p = Q.front(); Q.pop();
         for(int i=0; i<G[p].size(); i++) {
              if(!viz[ G[p][i] ]) {
                   dst[nod][ G[p][i] ] = dst[nod][p] + 1;
                   viz[ G[p][i] ] = 1;
                   Q.push( G[p][i] );
              }
         }
    }
}

int find(int nod, int dist) {
    if(!dist) return nod;
    return find(tt[nod], dist - 1);
}

int check(int D) {
    int i, j, pct = 0;

    memset(aj, 0, sizeof(aj));
    memset(used, 0, sizeof(used));

    for(i=0; i<V.size(); i++) {
         if(!used[ V[i].second ]) {
              //caut al D-lea stramos
              int str = find(V[i].second, D);
              if(str) {
                   aj[str] = 1;
                   //tot ce e la dist <= D marchez ca used
                   for(j=1; j<=N; j++) {
                        if(dst[str][j] <= D) {
                             used[j] = 1;
                        }
                   }
              }
         }
    }

    for(i=1; i<=N; i++) {
         if(aj[i]) pct ++;

    }
    if(pct <= K) {
         sol = D;
         aux.clear();
         for(i=1; i<=N; i++) {
              if(aj[i]) aux.pb(i);
         }

         if(pct < K) {
              if(!aj[1]) {
                   aux.pb(1);
                   aj[1] = 1;
                   pct ++;
              }
              for(i=1; i<=N && pct < K; i++) {
                   if(!aj[i]) {
                        aux.pb(i);
                        pct ++;
                   }
              }
         }

         sort(aux.begin(), aux.end());

         return 1;
    }

    return 0;
}

int main() {
    FILE *f1=fopen("salvare.in", "r"), *f2=fopen("salvare.out", "w");
    int i, p, q;

    fscanf(f1, "%d\n", &N);
    fscanf(f1, "%d\n", &K);
    for(i=1; i<N; i++) {
         fscanf(f1, "%d %d\n", &p, &q);
         G[p].pb(q); G[q].pb(p);
    }

    DFS(1, 0);
    for(i=1; i<=N; i++) {
         BFS(i);
    }
    for(i=1; i<=N; i++) {
         V.pb( mkp(lev[i], i) );
    }
    sort(V.begin(), V.end(), cmp);

    int ls = 0, ld = 2*N;
    while(ls <= ld) {
         int mij = (ls + ld) >> 1;
         if(check(mij)) {
              ld = mij - 1;
         }
         else {
              ls = mij + 1;
         }
    }

    fprintf(f2, "%d\n", sol);
    for(i=0; i<aux.size(); i++) {
         fprintf(f2, "%d ", aux[i]);
    } fprintf(f2, "\n");

    fclose(f1); fclose(f2);
    return 0;
}