Cod sursa(job #71501)

Utilizator info_arrandrei gigea info_arr Data 10 iulie 2007 19:57:07
Problema Salvare Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
using namespace std;
#define nmax 3005


#include<stdio.h>
#include<fstream>

FILE *fin=fopen("salvare.in","r"), 
     *fout=fopen("salvare.out","w");
     
int p,opt,nr,st,en,lo;
int hi,med,i,j,k,kk,l,m,n,mp;
int a[nmax][3];
int ok[nmax],dd[nmax],start[nmax],c[nmax],d[nmax],sol[nmax];
int t[nmax],x[nmax];

void read()
 {
     fscanf(fin,"%d",&n);
     fscanf(fin,"%d",&kk);
     for (i=1; i<=n-1; i++)
     {
      fscanf(fin,"%d%d",&a[i][1],&a[i][2]);
  //    fscanf(fin,"%d\n",&a[i][2]);
      a[n+i-1][1]=a[i][2];
      a[n+i-1][2]=a[i][1];
     }
 }

int tryhard()
 {
  int tryy;
  tryy=1;
  memset(ok,0,sizeof(ok));
  memset(c,0,sizeof(c));
  memset(x,0,sizeof(x));
  memcpy(d,dd,sizeof(dd));
  for (i=1; i<=n; i++) t[i]=999999;
  nr=0; st=1; en=0;
  for (i=1; i<=n; i++)
   if (d[i]==1)
    {
      en++;
      c[en]=i;
      t[i]=med;
    }
  while (en<n)
   {
      i=c[st];
      for (j=start[i]; j<=start[i+1]-1; j++)
      if (ok[j]==0)
    	{ ok[j]=1; k=a[j][2]; break; }
      d[i]--; d[k]--;
      if (t[i]<t[k]) t[k]=t[i];
      for (j=start[k]; j<=start[k+1]-1; j++)
       if (a[j][2]==i)
	   {ok[j]=1; break; }
      if (d[k]==1)
	    {
	     t[k]--;
	     if (t[k]==0)
	      {
	       x[k]=1;
	       t[k]=2*med+1;
	       nr++;
	      }
	     en++;
	     c[en]=k;
    	}
      st++;
   }
  if (nr==0)
   {
     nr=1;
     x[c[en]]=1;
   }
  if (nr<=kk)
   {
     tryy=0;
     if (med<opt)
      {
       opt=med;
       memcpy(sol,x,sizeof(x));
      }
   }
  return tryy; 
}            
                
void solve()
 {
    memset(sol,0,sizeof(sol)); 
    opt=n+1;
    m=2*n-2;
    for (i=1; i<=m; i++)
     {
      mp=i;   
        for (j=i+1; j<=m; j++)
         if ((a[j][1]<a[mp][1])||((a[j][1]==a[mp][1])&&(a[j][2]<a[mp][2])))                 
           mp=j; 
	  memcpy(a[m+1],a[mp],sizeof(a[mp]));
	  memcpy(a[mp],a[i],sizeof(a[i]));
	  memcpy(a[i],a[m+1],sizeof(a[m+1]));
	  memcpy(a[m+1],a[m+2],sizeof(a[m+2]));
     }  
    start[1]=1;
    j=1;
    for (i=2; i<=n; i++)
     {
       while (a[j][1]!=i) j++;
       start[i]=j;
     }
    start[n+1]=m+1;
    for (i=1; i<=n; i++)
     d[i]=start[i+1]-start[i];
     memcpy(dd,d,sizeof(d));
     lo=1;
     hi=n;
     while (lo<=hi)
      {
        med=(lo+hi)/2;
        if (tryhard()==0) hi=med-1;
         else lo=med+1;
      }
     p=kk;
     for (i=1; i<=n; i++)
      p-=sol[i];
     for (i=1; i<=n; i++)
      if (p>0 && sol[i]==0)
       {
          sol[i]=1;
          p--;
       }
     if (kk==n)
      opt=0;
     fprintf(fout,"%d\n",opt);
     for (i=1; i<=n; i++)
      if (sol[i]==1) fprintf(fout,"%d ",i);
     fprintf(fout,"\n");
}           
       
             
                 

int main()
{
  read();
  solve();
  fclose(fin); fclose(fout);
  return 0;
}