Cod sursa(job #55432)

Utilizator dominoMircea Pasoi domino Data 27 aprilie 2007 14:07:09
Problema Salvare Scor Ascuns
Compilator cpp Status done
Runda Marime 2.06 kb
#include <stdio.h>
#include <vector>

using namespace std;

#define nm 1024
#define km 305
#define pb push_back

int n, k, dist, nr, sol, step, used[nm], len[nm], minim[nm], maxim[2][nm], v[nm], d[nm], mat[nm][nm], c[nm][km], p[nm];
vector <int> a[nm];

void go(int nod)
{
	int i;

	used[nod] = 1;

	for (i = 1; i <= n; ++i)
		if (!used[i] && mat[nod][i])
		{
			go(i);
			a[nod].pb(i);
		}

	len[nod] = a[nod].size();
}

void go2(int nod)
{
	int i;

	if (len[nod] == 0)
	{
		minim[nod] = 1025;
		maxim[0][nod] = maxim[1][nod] = 0;
	}
	else
	{
		go2(a[nod][0]);

		minim[nod] = minim[a[nod][0]] + 1;
		maxim[0][nod] = maxim[0][a[nod][0]] + 1;
		maxim[1][nod] = maxim[1][a[nod][0]] + 1;

		for (i = 1; i < len[nod]; ++i)
		{
			go2(a[nod][i]);

			if (minim[nod] > minim[a[nod][i]] + 1)
				minim[nod] = minim[a[nod][i]] + 1;
		
			if (maxim[0][nod] < maxim[0][a[nod][i]] + 1)
				maxim[0][nod] = maxim[0][a[nod][i]] + 1;

			if (maxim[1][nod] < maxim[1][a[nod][i]] + 1)
				maxim[1][nod] = maxim[1][a[nod][i]] + 1;
		}
	}

	if (len[nod] > 1 && minim[nod] + maxim[0][nod] <= dist && minim[nod] + maxim[1][nod] <= 2 * dist + 1)
		maxim[1][nod] = minim[nod];

	if (maxim[0][nod] >= dist || maxim[1][nod] >= 2 * dist)
	{
		v[++nr] = nod;
		minim[nod] = 0;
		maxim[1][nod] = 0;
		maxim[0][nod] = -1000;
	}
}

int main()
{
	int i, x, y;

	freopen("salvare.in", "r", stdin);
	freopen("salvare.out", "w", stdout);

	scanf("%d%d", &n, &k);

	if (n == k)
	{
		printf("0\n");
		for (i = 1; i <= n; ++i)
			printf("%d ", i);
		printf("\n");

		return 0;
	}

	for (i = 1; i < n; ++i)
	{
		scanf("%d%d", &x, &y);
	
		mat[x][y] = mat[y][x] = 1;
	}

	go(1);

	for (sol = step = 256; step; step /= 2)
	{
		dist = sol - step;
		nr = 0;

		go2(1);

		if (minim[1] >= 1025)
			v[++nr] = 1;
		
		if (nr <= k)
		{
			sol -= step;
			d[0] = nr;
			for (i = 1; i <= nr; ++i)
				d[i] = v[i];
		}
	}

	printf("%d\n", sol);

	for (i = 1; i <= d[0]; ++i)
		p[d[i]] = 1;
	for (i = 1, nr = d[0]; nr < k; ++i)\
		if (!p[i])
		{
			p[i] = 1;
			++nr;
		}

	for (i = 1; i <= n; ++i)
		if (p[i])
			printf("%d ", i);
	printf("\n");

	return 0;
}