Cod sursa(job #7144)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 21 ianuarie 2007 12:50:11
Problema Radiatie Scor 0
Compilator cpp Status done
Runda preONI 2007, Runda 1, Clasele 11-12 Marime 5.25 kb
#include <stdio.h>

#define maxn 15010
#define maxm 30010
#define maxx 60010
#define maxv 1000000000
#define maxl 16

int n,m,k;
int g[maxn],t[maxn],sol[maxn],fol[maxn];
int x[maxm],y[maxm],z[maxm];
int a[maxx],c[maxx];

int cost[maxn],h[maxn],p[maxn],from[maxn],mark[maxn],from2[maxn];
int l,count,draw;
int s[maxn];
int min[maxl][maxm],rmq[maxl][maxm];

int v[maxx],grad[maxn],u[maxx],poz[maxn];
int din[maxl][maxn],str[maxl][maxn];
int gq[maxn];
int q[maxn];

int max(int a,int b)
{
    if (a>b) return a;
    return b;
}

void pop(int x)
{
     int aux;
     
     while ((x/2>1) && (cost[h[x]]<cost[h[x/2]]))
     {
           aux=h[x];
           h[x]=h[x/2];
           h[x/2]=aux;
           
           p[h[x]]=x;
           p[h[x/2]]=x/2;
           
           x=x/2;
     }
}

void push(int x)
{
     int aux,y=0;
     
     while (x!=y)
     {
           y=x;
           
           if ((y*2<=l) && (cost[h[x]]>cost[h[y*2]])) x=y*2;
           if ((y*2+1<=l) && (cost[h[x]]>cost[h[y*2+1]])) x=y*2+1;
           
           aux=h[x];
           h[x]=h[y];
           h[y]=aux;
           
           p[h[x]]=x;
           p[h[y]]=y;
     }
}

void Dijkstra(int nod)
{
     int i,aux;
     
     for (i=1;i<=count;i++)
     {
           cost[s[i]]=maxv;
		   h[i]=s[i];
		   p[s[i]]=i;
		   fol[s[i]]=1;
     }
       
     cost[nod]=0;
     h[1]=nod;
     p[nod]=1;
     h[nod]=1;
     p[1]=nod;
     l=count;
     
     while (l>0)
	 {
		   fol[h[1]]=0;
		   for (i=g[h[1]];i<g[h[1]+1];i++)
		   {
			  aux=max(c[i],cost[h[1]]);
			  if ((aux<cost[a[i]]) || (fol[a[i]]))
              {
                    cost[a[i]]=aux; 
                    from[a[i]]=h[1];
                    from2[a[i]]=c[i];
                    
                    pop(p[a[i]]);
              }
           }
              
           p[h[1]]=0;
           h[1]=h[l];
           p[h[1]]=1;
           h[l]=0;
           l--;
           
           if (l>1) push(1);
     }
}

void DFS(int nod)
{
     int i;
     mark[nod]=draw;
     count++;
     s[count]=nod;
     
     for (i=g[nod];i<g[nod+1];i++)
       if (!mark[a[i]]) DFS(a[i]);
}

void DFS2(int nod,int gr)
{
     int i;
     
	 min[0][++m]=gr;
	 rmq[0][m]=nod;
	 poz[nod]=m;

	 for (i=grad[nod];i<grad[nod+1];i++)
	 {
		 DFS2(v[i],gr+1);
		 min[0][++m]=gr;
		 rmq[0][m]=nod;
     }
}

void LCA()
{
     int i,j;
     
     for (j=1;j<maxl;j++)
       for (i=1;i<=m;i++)
         if ((i+(1<<(j-1))>m) || (min[j-1][i]<min[j-1][i+(1<<(j-1))]))
         {
               min[j][i]=min[j-1][i];
               rmq[j][i]=rmq[j-1][i];
         }
         else {
                  min[j][i]=min[j-1][i+(1<<(j-1))];
                  rmq[j][i]=min[j-1][i+(1<<(j-1))];
              }
}

void Build()
{
	 int i,j;

	 for (i=1;i<=count;i++)
	   for (j=grad[s[i]];j<grad[s[i]+1];j++)
	   {
		  din[0][v[j]]=u[j];
		  str[0][v[j]]=s[i];
	   }

	 for (j=1;j<maxl;j++)
	   for (i=1;i<=count;i++)
		 str[j][s[i]]=str[j-1][str[j-1][s[i]]];

	 for (j=1;j<maxl;j++)
	   for (i=1;i<=count;i++)
		 din[j][s[i]]=max(din[j-1][s[i]],din[j-1][str[j-1][s[i]]]);
}

int stram(int x,int y)
{
	int i=maxl,rez=0;
	i=10; //schimba aici

	while (i>=0)
	{
		  if (1<<i<=y)
		  {
			  if (din[i][x]>rez) rez=din[i][x];
			  x=str[i][x];
			  y-=(1<<i);
		  }
		  i--;
	}

	return rez;
}

int query(int x,int y)
{
	int px,py,aux,aux2,gx,gy;

	if (poz[x]<poz[y])
	{
	   aux=x;
	   x=y;
	   y=aux;
	}

	px=poz[x];
	py=poz[y];

    gx=min[0][px];
	gy=min[0][py];
    
    aux=t[py-px];
    
    if (min[aux][px]<min[aux][py-(1<<aux)+1]) 
    {
          aux2=min[aux][px];
          aux=rmq[aux][px];
    }
    else {
              aux2=min[aux][py-(1<<aux)+1];
              aux=rmq[aux][py-(1<<aux)+1];
         }
    
	return max(stram(x,gx-aux2),stram(y,gy-aux2));
}

int main()
{
    freopen("radiatie.in","r",stdin);
    freopen("radiatie.out","w",stdout);
    
	scanf("%d %d %d",&n,&m,&k);
	int i,j,i2;

	t[1]=0;

	for (i=2;i<=n;i++)
	  if (1<<(t[i-1]+1)<=i) t[i]=t[i-1]+1;
	  else t[i]=t[i-1];

	for (i=1;i<=m;i++)
	{
		scanf("%d %d %d",&x[i],&y[i],&z[i]);
		g[x[i]]++;
		g[y[i]]++;
	}

	for (i=2;i<=n+1;i++) g[i]+=g[i-1];

	for (i=1;i<=m;i++)
	{
		a[g[x[i]]]=y[i];
		c[g[x[i]]--]=z[i];
		a[g[y[i]]]=x[i];
		c[g[y[i]]--]=z[i];
	}

	for (i=1;i<=n+1;i++) g[i]++;

	for (i=1;i<=k;i++)
	{
		scanf("%d %d",&x[i],&y[i]);
		gq[x[i]]++;
	}

	for (i=2;i<=k+1;i++) gq[i]+=gq[i-1];

	for (i=1;i<=k;i++)
	  q[gq[x[i]]--]=i;

	for (i=1;i<=k+1;i++) gq[i]++;

	for (i=1;i<=n;i++)
	  if (!mark[i])
	  {
		  count=0;
		  ++draw;
		  DFS(i);
		  Dijkstra(i);

		  for (j=1;j<=count+1;j++) grad[j]=0;

		  for (j=2;j<=count;j++) grad[from[s[j]]]++;

		  for (j=2;j<=count+1;j++) grad[j]+=grad[j-1];

		  for (j=2;j<=count;j++)
		  {
			  u[grad[from[s[j]]]]=from2[s[j]];
			  v[grad[from[s[j]]]--]=s[j];
		  }

		  for (j=1;j<=count+1;j++) grad[j]++;

		  m=0;
		  DFS2(i,1);

		  LCA();
		  Build();

		  for (j=1;j<=count;j++)
			for (i2=gq[s[j]];i2<gq[s[j]+1];i2++) sol[q[i2]]=query(x[q[i2]],y[q[i2]]);
	  }

	  for (i=1;i<=k;i++) printf("%d\n",sol[i]);

	  return 0;
}