Cod sursa(job #552205)

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

int N, K, D, sol;
int aj[maxn], viz[maxn], fol[maxn], tt[maxn], dst[maxn], used[maxn];
vector<int> G[maxn], aux, fii;

int cmp(int a, int b) {
    return dst[a] > dst[b];
}

void add(int nod, int dist) {
    used[nod] = max(used[nod], dist);
    if(tt[nod]) {
         add(tt[nod], dist - 1);
    }
}

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

    fol[nod] = 1;
    fii.clear();
    for(int i=0; i<G[nod].size(); i++) {
         if(fol[ G[nod][i] ]) fii.pb( G[nod][i] );
    }

    if(!fii.size()) {
         dst[nod] = 0;
    }
    else {
         for(int i=0; i<fii.size(); i++) {
              if(dst[ fii[i] ] + 1 > used[nod] && dst[ fii[i] ] + 1 >= D) {
                   //sunt obligat sa pun punct de ajutor in nodul nod
                   add(nod, D);
                   aj[nod] = 1;
                   break;
              }
         }

         if(aj[nod]) {
              dst[nod] = 0;
         }
         else {
              for(int i=0; i<fii.size(); i++) {
                   if(!aj[ fii[i] ]) {
                        dst[nod] = max(dst[nod], dst[ fii[i] ] + 1);
                   }
              }
         }
    }
}

void ioi(int nod, int dist) {
    viz[nod] = 1;
    if(!dist) return;
    for(int i=0; i<G[nod].size(); i++) {
         if(!viz[ G[nod][i] ]) ioi(G[nod][i], dist - 1);
    }
}

int verif() {
    memset(viz, 0, sizeof(viz));
    for(int i=1; i<=N; i++) {
         if(aj[i]) ioi(i, D);
    }
    for(int i=1; i<=N; i++) {
         if(!viz[i]) return 0;
    }
    return 1;
}

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

    memset(aj, 0, sizeof(aj));
    memset(viz, 0, sizeof(viz));
    memset(fol, 0, sizeof(fol));
    memset(tt, 0, sizeof(tt));
    memset(used, 0, sizeof(used));
    memset(dst, 0, sizeof(dst));
    DFS(1);

    for(i=1; i<=N; i++) {
         if(aj[i]) pct ++;
    }
    if(!verif()) {
         if(!aj[1]) {
              aj[1] = 1;
              pct ++;
         }
    }
    if(pct <= K) {
         sol = dist;
         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);
    }

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