Pagini recente » Cod sursa (job #2797324) | Cod sursa (job #2709921) | Cod sursa (job #2943570) | Cod sursa (job #79128) | Cod sursa (job #166332)
Cod sursa(job #166332)
#include <stdio.h>
#include <string.h>
#define MAX 1002
/* variabile globale */
long p,opt,nr,st,en,lo,hi,med,i,j,k,l,m,n,mp;
int dd[MAX],start[MAX],d[MAX],sol[MAX];
long a[2*MAX][2]; /* reprezentare graf */
long ok[2*MAX];
int try(){
int c[MAX], t[MAX],x[MAX], kk;
int try = 0; /* false */
for (i=0; i<MAX; i++){
ok[i]=c[i]=x[i]=0;
}
// ok = pentru fiecare latura
// c = coada de varfuri
// x = salutie partiala
//d=dd;
memcpy(d, dd, sizeof(dd));
for(i=0;i<n;i++){
t[i]=9999; // timp rezolvare
}
nr=0; // nr. puncte salvare
// bag in coada frunzele si trimit in sus
st=0;
en=-1;
for(i=0;i<n;i++)
if (d[i]==1){
en++;
c[en]=i;
t[i]=med;
}
while (en<n-1){
// scade gradul vecinului lui st
// daca acesta are gradul 0, il baga in coada
i=c[st];
for(j=start[i];j<=start[i+1]-1;j++)
if (ok[j]==0){
ok[j]=1;
kk=a[j][1];
break;
}
d[i]--;
d[kk]--;
if (t[i]<t[kk])
t[kk]=t[i];
for(j=start[kk];j<=start[kk+1]-1;j++)
if (a[j][1]==i){
ok[j]=1;
break;
}
if (d[kk]==1){
t[kk]=t[kk]-1;
if (t[kk]==0){
x[kk]=1;
t[kk]=2*med+1;
nr++;
}
en++;
c[en]=kk;
}
st++;
}
/* daca nu am fixat niciun punct il fixam pe ultimul din coada */
if (nr==0){
nr=1;
x[c[en]]=1;
}
/* am gasit solutie */
if (nr<=k){
try=1;
if (med<opt){
opt=med;
/* sol = solutia partiala */
memcpy(sol, x, sizeof(x));
}
}
return try;
}
void solve(){
opt=n+1; // timpul de rezolvare maxim
m=2*n-2; //
/* ordonare crescatoare dupa primul varf */
for(i=0;i<m;i++){
mp=i;
for(j=i+1;j<m;j++)
if ((a[j][0]<a[mp][0])||((a[j][0]==a[mp][0])&&(a[j][1]<a[mp][1])))
mp=j;
/* interschimb */
for (j=0; j<2; j++){
a[m][j]=a[mp][j];
a[mp][j]=a[i][j];
a[i][j]=a[m][j];
a[m][j]=a[m+1][j];
}
}
/*
for (i=0; i<m; i++){
printf("%ld %ld\n", a[i][0], a[i][1]);
}
*/
/* se determina:
* - start[i] = prima muchie care are nod de plecare i
* - d[i] = gradul nodului i
*/
start[0]=0;
j=0;
for(i=1;i<n;i++){
do{
j++;
}while(a[j][0]!=i);
start[i]=j;
}
start[n]=m;
for(i=0;i<n;i++)
d[i]=start[i+1]-start[i];
/* salveaza d */
for (i=0; i<n; i++)
dd[i] = d[i];
/*
for (i=0; i<n; i++)
printf("%ld ", d[i]);
*/
/* urmeaza cautarea binara */
lo=1;
hi=n;
while(lo<=hi){
//begin
med=(lo+hi) / 2;
if (try())
hi=med-1;
else
lo=med+1;
//end;
}
p=k; // k = nr. de posturi salvare
/* cate posturi de salvare avem ? */
for(i=0;i<n;i++)
p=p-sol[i];
/* daca nu sunt k posturi, se completeaza pana la k in ordine crescatoare */
for(i=0;i<n;i++)
if ((p>0) && (sol[i]==0)){
//begin
sol[i]=1;
p--;
//end;
}
if (k==n) /* caz particular - ar trebui tratat mai devreme */
opt=0;
}
int main(){
/* variabile */
FILE *f;
char fin[15] = "salvare.in", fout[15] = "salvare.out";
/* citire date */
f = fopen(fin, "rt");
if (!f){
printf("Eroare fisier intrare!\n");
return -1;
}
fscanf(f, "%ld %ld", &n, &k);
for (i=0; i<n-1; i++){
fscanf(f, "%ld %ld", &a[i][0], &a[i][1]);
a[i][0]--; // pt reprezentare interna
a[i][1]--;
a[n-1+i][0]=a[i][1];
a[n-1+i][1]=a[i][0];
}
fclose(f);
/* algoritm */
solve();
/* afisare date */
f = fopen(fout, "wt");
fprintf(f,"%ld\n", opt); /* maximum timpilor de rezolvare */
for(i=0;i<n;i++)
if (sol[i]==1)
fprintf(f, "%ld ",i+1); /* punctele de salvare */
fprintf(f,"\n");
fclose(f);
return 0;
}