Cod sursa(job #355748)

Utilizator Mishu91Andrei Misarca Mishu91 Data 12 octombrie 2009 00:20:39
Problema Salvare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.7 kb
#include <fstream>
#include <queue>
#include <bitset>
#include <vector>

using namespace std;

#define MAX_N 1005
#define MAX_K 305
#define INF 0x3f3f3f3f

#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it)
#define act *it

ifstream fin ("salvare.in");
ofstream fout ("salvare.out");

int N, K, M;
int Up[MAX_N], Jos[MAX_N];
vector <int> G[MAX_N], Sol, Solf;
bitset <MAX_N> Leaf, ales, viz;

void citire()
{
	fin >> N >> K;

	for(int i = 1; i < N; ++i)
	{
		int x, y;

		fin >> x >> y;
		G[x].push_back(y);
		G[y].push_back(x);
	}

	for(int i = 1; i <= N; ++i)
		if(G[i].size() == 1)
			Leaf[i] = 1;
}

void df(int nod)
{
	viz[nod] = 1;
	int josmax = 0;

	foreach(G[nod])
	{
		if(viz[act]) continue;

		df(act);

		if(Jos[nod] > Jos[act])
			Jos[nod] = Jos[act]+1,
			josmax = act;
	}

	if(Leaf[nod])
		Up[nod] = 0;

	
	foreach(G[nod])
		if(Up[act] + Jos[nod] + 1 > M || act == josmax)
			Up[nod] = max(Up[nod], Up[act]+1);

	if(Up[nod] == M)
		Up[nod] = -M - 1, Sol.push_back(nod), Jos[nod] = 0, ales[nod] = 1;

	if(nod == 1 && Up[nod] > 1)
		Sol.push_back(1), ales[nod] = 1;
}

bool ok(int x)
{
	M = x;
	viz.reset();
	ales.reset();
	Sol.clear();
	memset(Up, -INF, sizeof Up);
	memset(Jos, INF, sizeof Jos);

	df(1);

	if((int)Sol.size() <= K)
	{
		int cnt = K - Sol.size();

		for(int i = 1; (i <= N) && cnt; ++i)
			if(ales[i] == 0)
				Sol.push_back(i),
				--cnt;

		Solf.assign(Sol.begin(), Sol.end());

		return true;
	}

	return false;
}

void solve()
{
	int lg, i;
	for(lg = 1; lg <= N; lg <<= 1);

	for(i = N; lg; lg >>= 1)
		if(i - lg >= 0 && ok(i - lg))
		   i -= lg;

	fout << i << "\n";

	sort(Solf.begin(), Solf.end());
	foreach(Solf)
		fout << act << " ";
}

int main()
{
	citire();
	solve();
}