Cod sursa(job #218493)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 2 noiembrie 2008 12:03:03
Problema Salvare Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.13 kb
using namespace std;

#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <queue>

#define pb push_back
#define sz size
#define II inline
#define abs(x) x>0 ? x:-x
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define IN "salvare.in"
#define OUT "salvare.out"
#define oo 16843009
#define N_MAX 1<<10

int N,K;
typedef vector<int> VI;
vector< vector<int> > A(N_MAX);
bool sol[N_MAX],viz[N_MAX];
int Di[N_MAX],D[N_MAX],H[N_MAX],T[N_MAX],F[N_MAX];


struct Comp{bool operator ()
	(int i,int j)
	{
		return H[i] < H[j];
	}
};
priority_queue<int, VI, Comp> stv;

II void scan()
{
	int x,y;
	freopen(IN,"r",stdin);
	freopen(OUT,"w",stdout);
	scanf("%d\n%d\n",&N,&K);
	FOR(i,1,N-1)
	{
		scanf("%d %d\n",&x,&y);
		A[x].pb(y);
		A[y].pb(x);
	}	
}	
	
void BF(int nod)
{
	viz[nod] = true;
	int l = A[nod].sz() - 1;
	FOR(i,0,l)
	{
		int fiu = A[nod][i];
		if(!viz[fiu])
		{
			T[fiu] = nod;
			H[fiu] = H[nod] + 1;
			BF(fiu);
		}
	}	
}

II int make(int dist)
{
	int nr(0);
	memset(viz,0,sizeof(viz));
	memset(D,1,sizeof(D));
	memset(sol,0,sizeof(sol));
	memset(Di,0,sizeof(D));
	
	FOR(i,1,F[0])
		stv.push(F[i]),
		D[ F[i] ] = oo,
		Di[ F[i] ] = 0,
		viz[ F[i] ] = true;
	
	for(int nod;!stv.empty();)
	{
		nod = stv.top();
		stv.pop();
		int tata = T[nod];
		if( ( (Di[nod] == dist || !tata) && D[nod] == oo) || (Di[nod] > (dist<<1) && D[nod] != oo) || (Di[nod] > dist && !tata)  )
		{
			Di[nod] = D[nod] = 0;
			sol[nod] = true;
			++nr;
		}	
		if(nod == 1)
			continue;
		if(!viz[tata])
		{
			D[tata] = min(D[nod]+1,oo);
			Di[tata] = Di[nod] + 1;
			viz[tata] = true;
			stv.push(tata);
			continue;
		}
		if(D[tata] == oo && D[nod] != oo && Di[nod] + 1 + Di[tata] <= dist)
		{
			D[tata] = D[nod] + 1;
			Di[tata] = min(Di[nod] + 1,Di[tata]);
			continue;
		}
		if(D[tata] != oo && D[nod] == oo && D[tata] + Di[nod] + 1 <= dist)
		{
			Di[tata] = min(Di[tata],Di[nod]+1);
			continue;
		}
		if(D[tata] == oo && D[nod] == oo)
		{
			Di[tata] = min(Di[tata],Di[nod]+1);
			continue;
		}
		if(D[tata] != oo && D[nod] != oo)
		{
			int a = min(D[nod]+1,D[tata]);
			int b = max(D[nod]+1,D[tata]);
			if(a + abs(dist-b) <= dist)
				D[tata] = a,
				Di[tata] = a;
			else
				D[tata] = b,
				Di[tata] = b;
			continue;
		}	
		D[tata] = oo;
		if(D[nod] == oo)
			Di[tata] = max(Di[nod]+1,Di[tata]);
		else
			Di[tata] = max(Di[tata],abs(Di[nod]+1-dist) );
	}	
	return nr;
}

II void solve()
{
	BF(1);
	memset(viz,0,sizeof(viz));
	FOR(i,1,N_MAX)
		viz[ T[i] ] = true;
	FOR(i,1,N)
		if(!viz[i])
			F[++F[0]] = i;
	memset(viz,0,sizeof(viz));	
	
	int m,step;
    for(step = 1; step <= N; step <<= 1);
    for(m = 0; step; step >>= 1)
        if( m + step <= N && make(m + step - 1) > K)
			m += step;
	make(m);	
	printf("%d\n",m);
	
	srand((int)time(0));
	int nr(0);
	FOR(i,1,N)
		if(sol[i] == true)
			++nr;
	for(;nr < K;++nr)
	{	
		int aux;
		for(aux=rand()%N+1;sol[aux];aux=rand()%N+1);
		sol[aux] = true;
	}	
	FOR(i,1,N)
		if(sol[i] == true)
			printf("%d ",i);
}

int main()
{
	scan();
	solve();
	return 0;
}