Cod sursa(job #40490)

Utilizator pocaituDavid si Goliat pocaitu Data 27 martie 2007 14:24:38
Problema Cerere Scor 35
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.31 kb
#include<stdio.h>
#include<fstream.h>
#define nmax 100000
#define fmax 100
long k[nmax],rad,p[nmax],fiu[nmax][fmax],str[20][nmax],min[nmax],n,s[nmax],niv[nmax];
void DF(long,long);
void citire()
{long i,a,b;
 freopen("cerere.in","r",stdin);
 scanf("%ld",&n);
 for(i=1;i<=n;i++)
   scanf("%ld",&k[i]);
 for(i=1;i<n;i++)
  {scanf("%ld%ld",&a,&b);
	 p[b]=a;
   fiu[a][++fiu[a][0]]=b;
   }
 for(i=1;i<=n;i++)
  if(!p[i])
	rad=i;

 }
void init()
{long i;
 memset(min,-1,sizeof(min));
 for(i=1;i<=n;i++)
  if(!k[i]) min[i]=0;
 DF(rad,0);

 for(i=1;i<=n;i++)
  if(min[i]==-1)
	if(!k[s[i]])
	   min[i]=1;
	else str[0][i]=s[i];

 }

void DF(long x,long n)
{long i;
 niv[n]=x;
 s[x]=niv[n-k[x]];
 for(i=1;i<=fiu[x][0];i++)
   DF(fiu[x][i],n+1);
 }

void rezolva()
{long d,i;

for(d=1;1<<d<=n;d++)
 for(i=1;i<=n;i++)
   if(min[i]==-1)
	{if(min[str[d-1][i]]==-1)
		{str[d][i]=str[d-1][str[d-1][i]];
		 if(!k[str[d][i]])
		   min[i]=(long)1<<d;
		 }
	 else
		{str[d][i]=str[d-1][str[d-1][i]];
		 //if(!k[str[d][i]])
		 min[i]=min[str[d-1][i]]+((long)1<<d-1);
		 }
	 }
 }

void afisare()
{long i;
 freopen("cerere.out","w",stdout);
 for(i=1;i<=n;i++)
  printf("%ld ",min[i]);
 fclose(stdout);
 }

int main()
{citire();
 init();
 rezolva();
 afisare();
 return 0;
 }