Cod sursa(job #1560739)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 3 ianuarie 2016 03:41:12
Problema Salvare Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <fstream>
#include <iterator>
#include <functional>
#include <numeric>
#include <algorithm>
#include <vector>
using namespace std;

constexpr int rad = 0, bad_nod = -1;

int find_unmarked_lowest_nod(const vector<int>& adanc, const vector<bool>& mark){
	int rez = rad, ad_cur = 0;
	for(int i = 0; i < adanc.size(); ++i){
		if(!mark[i] && adanc[i] > ad_cur){
			rez = i; } }
	return rez; }

void mark_dfs(const int cur, const int ad_max,
	const vector<vector<int>>& vec, vector<bool>& mark,
	const int prev = bad_nod, const int ad_cur = 0){
	mark[cur] = true;
	if(ad_cur < ad_max){
		for(const auto next : vec[cur]){
			if(next != prev){
				mark_dfs(next, ad_max, vec, mark, cur, ad_cur+1); } } } }

void adanc_dfs(const int cur, const vector<vector<int>>& vec,
	vector<int>& adanc, vector<int>& tata, const int prev = bad_nod,
	const int ad_cur = 0){
	adanc[cur] = ad_cur;
	tata[cur] = prev;

	for(const auto next : vec[cur]){
		if(next != prev){
			adanc_dfs(next, vec, adanc, tata, cur, ad_cur+1); } } }

template <typename Pred>
int cbin(int st, const int dr, Pred pred){
	// Pred = fffffaaaaaa
	// cea mai mare valoare care e falsa intre st si dr
	// daca toate sunt adevarate, returneaza st-1;
	if(pred(st)){
		return st-1; }
	for(int step = 1<<(int)log2(dr-st+1), tmp; step > 0; step /= 2){
		if((tmp=st+step) <= dr && !pred(tmp)){
			st = tmp; } }
	return st; }

template <typename It>
int cnt_necesary(const vector<vector<int>>& vec, const vector<int>& adanc, const vector<int>& tata,
	const int d, It marked){

	const int n = vec.size();
	vector<bool> mark(n, false);
	int rez = 0;
	for( ; !all_of(begin(mark), end(mark), [](const bool b){ return b; }); ++rez){

		int todo = find_unmarked_lowest_nod(adanc, mark);
		for(int j = 0; j < d && tata[todo] != bad_nod; ++j){
			todo = tata[todo]; }

		*(marked++) = todo;

		mark_dfs(todo, d, vec, mark); }
	return rez; }

struct null_type{
	template <typename T>
	null_type& operator=(const T& rhs){
		return *this; } };

struct null_iterator{
	null_type n;
	null_iterator& operator++(int){
		return *this; }
	null_type& operator*(){
		return n; } } n_it;

int main(){
	ifstream f("salvare.in");
	ofstream g("salvare.out");

	int n, k;
	f >> n >> k;

	vector<vector<int>> vec(n);

	for(int i = 0, a, b; i < n-1; ++i){
		f >> a >> b;
		--a, --b;

		vec[a].push_back(b);
		vec[b].push_back(a); }

	vector<int> adanc(n, 0), tata(n, 0);

	adanc_dfs(rad, vec, adanc, tata);

	const int dist = cbin(0, n, [&](const int d){
		return cnt_necesary(vec, adanc, tata, d, n_it) <= k; })+1;

	g << dist << '\n';

	vector<int> noduri(k);
	cnt_necesary(vec, adanc, tata, dist, begin(noduri));

	sort(begin(noduri), end(noduri));

	for(const auto x : noduri){
		g << x+1 << ' '; }

	return 0; }