Pagini recente » Cod sursa (job #1847632) | Cod sursa (job #2083171) | Cod sursa (job #2718136) | Cod sursa (job #2681681) | Cod sursa (job #834834)
Cod sursa(job #834834)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>
using namespace std;
ifstream f("salvare.in");
ofstream g("salvare.out");
#define nmax 1005
#define ll long long
int n, K, t[nmax], vindecat[nmax], aux[nmax], rez[nmax];
bool spital[nmax], viz[nmax];
vector<int> gf[nmax];
void citeste(){
f >> n;
f >> K;
for(int i=1; i<n; ++i){
int x, y;
f >> x >> y;
gf[x].push_back(y);
gf[y].push_back(x);
}
}
void dfs(int nod){
viz[nod] =1;
for(int i=0; i<gf[nod].size(); ++i){
int vc = gf[nod][i];
if (viz[vc] == 1) continue;
t[vc] = nod;
dfs(vc);
}
aux[++aux[0]] = nod;
}
int afla_tata(int nod, int val){
int cnt = 0;
for(; t[nod]!=0 && cnt<val; ++cnt, nod=t[nod]);
return nod;
}
void baga_dfs(int nod, int x){
if (x <= 0) return;// daca nuami pot ajuta
vindecat[nod] = x;
for(int i=0; i<gf[nod].size(); ++i){
int vc = gf[nod][i];
if (vindecat[vc] < x - 1){//daca vecinul era ajuta de un spital care se afla mai departe decat asta de acum
// il iau pe asta pt ca exista sansa sa mai vindec ceva noduri pe care nu le-am vindetcat cu spitalul precedent
baga_dfs(vc, x-1);
}
}
}
inline bool tot(){
int ok =1;
for(int i=1; i<=n; ++i)
if (vindecat[i] <= 0){
ok = 0;
break;
}
return ok;
}
void init(){
for(int i=1; i<=n; ++i) vindecat[i] = 0, spital[i] = 0;
}
inline bool pot(int T){
init();
int cnt = 0;
for(int i=1; i<=n; ++i){
int nod = aux[i];
if (vindecat[nod] > 0) continue;
int tata = afla_tata(nod, T);
//acum bag un dfs din acest nod; evident daca nu e vindecat;
//cout << tata << "\n";
//bag aici un spital
++cnt;
spital[tata] = 1;
baga_dfs(tata, T+1);
}
if (cnt <= K ) return 1;
return 0;
}
void rezolva(){
// caut binar raspunsul; apoi pentru un T fixat pornesc din frunze si tot bag spitale la distante T fata de nodul la care ma aflu;
// fie ca ma aflu in nodul X; ii iau al Tlea tata si din acest nod marhez toate nodurile la care pot ajunge intr-un timp T;
// vin de jos in sus pe arbore ;
dfs(1);
//cout <<pot(1);
int st = 0;
int dr = nmax;
while(dr - st>1){
int mij = (st + dr) / 2;
if ( pot(mij) == 1 ){
//cout << dr << '\n';
dr = mij;
for(int i=1; i<=n; ++i){
rez[i] = spital[i];
}
}else st = mij;
}
//cout << dr << "\n";
g << dr << "\n";
int cnt =0;
for(int i=1; i<=n; ++i){
viz[i] = rez[i];
if (viz[i] ==1) ++cnt;
}
if (cnt < K){
for(int j=1; j<=n && cnt <K; ++j){
if (viz[j] == 0){
++cnt;
viz[j] = 1;
}
}
}
for(int i=1; i<=n; ++i){
if (viz[i] == 1) g << i << " ";
}
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}