Pagini recente » Cod sursa (job #37313) | Cod sursa (job #271342) | Cod sursa (job #2226345) | Cod sursa (job #1142006) | Cod sursa (job #180360)
Cod sursa(job #180360)
#include <stdio.h>
#define NM 1005
int n, m, i, j, k, opt = NM, kk, nr, p;
int dd[NM], d[NM], t[NM], x[NM], c[NM];
int sol[NM], s, e;
typedef struct nod {
int vf, s;
nod* urm;
} NOD, *PNOD;
PNOD l[NM];
void Add(int i, int j);
void Cbin(int st, int dr);
int Ok(int dist);
void Solve();
int main()
{
freopen("salvare.in", "r", stdin);
freopen("salvare.out", "w", stdout);
scanf("%d %d", &n, &kk);
for ( k = 1; k < n; k++ )
{
scanf("%d %d", &i, &j);
dd[i]++, dd[j]++;
Add(i, j);
Add(j, i);
}
Cbin(1, n); // cautam valoarea optima
p = kk;
for ( i = 1; i <= n ; i++ )
p -= sol[i]; // p - numarul de puncte de salvare gasite
for ( i = 1; i <= n; i++ )
if ( p > 0 && sol[i] == 0 ) // punem puncte de salvare pana cand p = kk
{
sol[i] = 1;
p--;
}
if ( kk == n ) opt = 0;
printf("%d\n", opt);
for ( i = 1; i <= n; i++ )
if ( sol[i] ) printf("%d ", i);
printf("\n");
return 0;
}
void Add(int i, int j)
{
PNOD q = new NOD;
q->vf = j;
q->s = 0;
q->urm = l[i];
l[i] = q;
}
void Cbin(int st, int dr)
{
if ( st == dr ) return;
int mij = (st+dr)/2;
if ( Ok(mij) ) Cbin(st, mij);
else Cbin(mij+1, dr);
}
int Ok(int dist)
{
for ( i = 1; i <= n; i++ )
c[i] = x[i] = 0, t[i] = 9999, d[i] = dd[i]; // t[i] = distanta de la i pana la cel mai indepartat
// punct de salvare
for ( i = 1; i <= n; i++ )
for ( PNOD q = l[i]; q; q = q->urm ) q->s = 0;
nr = 0;
s = 1, e = 0;
for ( i = 1; i <= n; i++ ) // introducem in coada frunzele
if ( d[i] == 1 )
{
e++;
c[e] = i, t[i] = dist;
}
while ( s <= e ) // cat timp mai am noduri in graf
{
i = c[s];
PNOD q;
for ( q = l[i]; q; q = q->urm ) // aleg k = "tatal" lui i
if ( !q->s )
{
q->s = 1;
k = q->vf;
break;
}
d[i]--, d[k]--; // sterg muchia
for ( q = l[k]; q; q = q->urm ) // o sterg din lista de vecini a lui k
if ( q->vf == i )
{
q->s = 1;
break;
}
if ( t[i] < t[k] ) t[k] = t[i]; // daca distanta maxima din i pana la punctul de salvare
// este mai mica decat cea din k, actualizam
if ( d[k] == 1 ) // in cazul in care k devine frunza
{
t[k]--; // ii scadem costul
if ( t[k] == 0 ) // daca este punct de salvare
{
x[k] = 1;
t[k] = 9999;
nr++;
}
e++; // il bagam in coada
c[e] = k;
}
s++;
}
if ( !nr ) // in cazul in care nu am gasit puncte de salvare, punem unul in ultimul nod sters
nr = 1, x[c[e]] = 1;
if ( nr <= kk ) // daca am gasit o solutie valida
{
if ( dist < opt ) // actualizam minimul
{
opt = dist;
for ( i = 1; i <= n; i++ ) sol[i] = x[i]; // si copiem solutia
}
return 1;
}
return 0;
}