Cod sursa(job #10826)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 29 ianuarie 2007 18:13:14
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.81 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

#define maxx 30010
#define maxn 15010
#define maxl 16

int n,m,T,l,X,Y;
int x[maxx],y[maxx],z[maxx],p[maxx],a[maxx],cost[maxx];
int com[maxn],mark[maxn],g[maxn],niv[maxn];
int v[maxl][maxx],rmq[maxl][maxx],t[maxx];
int c[maxl][maxn],d[maxl][maxn],s[maxn];

void Build()
{
     int i;
     
     for (i=1;i<=m;i++) 
     {
         g[x[i]]++;
         g[y[i]]++;
     }
     
     for (i=1;i<=n+1;i++) g[i]+=g[i-1];
     
     for (i=1;i<=m;i++)
     {
         a[g[x[i]]]=y[i];
         cost[g[x[i]]--]=z[i];
         a[g[y[i]]]=x[i];
         cost[g[y[i]]--]=z[i];
     }
     
     for (i=0;i<=n+1;i++) g[i]++;
}

void DFS(int nod,int gr)
{
     int i;
     
     niv[nod]=gr;
     l++;
     v[0][l]=gr;
     rmq[0][l]=nod;
     p[nod]=l;
     
     for (i=g[nod];i<g[nod+1];i++)
       if (niv[a[i]]==0)
       {
            c[0][a[i]]=nod;
            d[0][a[i]]=cost[i];
            DFS(a[i],gr+1);
            l++;
            v[0][l]=gr;
            rmq[0][l]=nod;
       }
}

int cmp(int x,int y)
{
   return z[x]<z[y];
}

int drum(int x)
{
    if (com[x]!=x) com[x]=drum(com[x]);
    
    return com[x];
}

void APM()
{
     int i,aux=m,sx[maxn],sy[maxn],sz[maxn];
     
     for (i=1;i<=n;i++) com[i]=i;
     m=0;
     
     for (i=1;i<=aux&&m<n-1;i++)
       if (drum(x[p[i]])!=drum(y[p[i]]))
       {
            m++;
            sx[m]=x[p[i]];
            sy[m]=y[p[i]];
            sz[m]=z[p[i]];
			com[drum(x[p[i]])]=drum(y[p[i]]);
       }
     
     for (i=1;i<=m;i++)
     {
         x[i]=sx[i];
         y[i]=sy[i];
         z[i]=sz[i];
     }
}

void LCA()
{
     int i,j;
     
     t[1]=0;
     for (i=2;i<=l;i++) 
       if (1<<(t[i-1]+1)<=i) t[i]=t[i-1]+1;
       else t[i]=t[i-1];
       
     for (j=1;j<maxl;j++)
       for (i=1;i<=l;i++)
         if ((i+(1<<(j-1))>l) || (v[j-1][i]<v[j-1][i+(1<<(j-1))]))
         {
              v[j][i]=v[j-1][i];
              rmq[j][i]=rmq[j-1][i]; 
         }
         else {
                   v[j][i]=v[j-1][i+(1<<(j-1))];
                   rmq[j][i]=rmq[j-1][i+(1<<(j-1))];
              }
}

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

void Stramosi()
{
     int i,j;
          
	 for (j=1;j<maxl;j++)
	   for (i=1;i<=n;i++)
	   {
		   c[j][i]=c[j-1][c[j-1][i]];
		   d[j][i]=max(d[j-1][i],d[j-1][c[j-1][i]]);
	   }
}

int find(int x,int y)
{
    int i=maxl-1,rez=0;
    
    while (i>=0)
    {
          if (1<<i<=y)
          {
              if (d[i][x]>rez) rez=d[i][x];
              x=c[i][x];
              y-=(1<<i);
          }
          i--;
    }
    
    return rez;
}

int query(int x,int y)
{
    int px,py,aux;
    
    if (p[x]>p[y])
    {
        aux=x;
        x=y;
        y=aux;  
    }
    
    px=p[x];
    py=p[y];
    aux=t[px-py+1];
    
    if (v[aux][px]<v[aux][py-(1<<aux)+1]) aux=rmq[aux][px];
    else aux=rmq[aux][py-(1<<aux)+1];
    
	return max(find(x,niv[x]-niv[aux]),find(y,niv[y]-niv[aux]));
}

int main()
{
    freopen("radiatie.in","r",stdin);
    freopen("radiatie.out","w",stdout);
    
    int i,j;
    scanf("%d %d %d",&n,&m,&T);
    
    if (n>20) return 2;
        
    for (i=1;i<=m;i++)
    {
        scanf("%d %d %d",&x[i],&y[i],&z[i]);
        p[i]=i;
    }
    
    sort(p+1,p+m+1,cmp);
    
    APM();
    
    for (i=1;i<=n;i++) 
      if (!mark[drum(i)])
      {
          mark[drum(i)]=1;
          m++;
          x[m]=0;
		  y[m]=i;
          z[m]=0;
      }
      
    Build();    
    
    DFS(0,1);
    
    LCA();
    
    Stramosi();
        
    for (i=1;i<=T;i++)
    {
        scanf("%d %d",&X,&Y);
        printf("%d\n",query(X,Y));
    }
    
    return 0;
}