Cod sursa(job #1814397)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 23 noiembrie 2016 22:10:33
Problema Radiatie Scor 100
Compilator cpp Status done
Runda cerculdeinfo-lectia7-grafuri Marime 3.43 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#define MAXN 15000
#define MAXM 30000
#define ROOT 1
#define LOG 18
struct Muchie{
    int a;
    int b;
    int c;
    bool operator <(const Muchie &a) const{
       return c<a.c;
    }
};
Muchie V[MAXM+1];
int sef[MAXN+1];
int myfind(int x){
    if(sef[x]==0)
       return x;
    return sef[x]=myfind(sef[x]);
}
inline void myunion(int x,int y){
    sef[myfind(x)]=myfind(y);
}
struct Edge{
   int nod;
   int val;
};
std::vector <Edge> G[MAXN+1];
inline void add_Edge(int a,int b,int c){
    G[a].push_back({b,c});
}
int lvl[MAXN+1];
void DFS(int nod){
    int i;
    for(i=0;i<G[nod].size();i++)
      if(lvl[G[nod][i].nod]==0){
         lvl[G[nod][i].nod]=lvl[nod]+1;
         DFS(G[nod][i].nod);
      }
}
int euler[2*MAXN+1];
int first[MAXN+1];
int rmq[2*MAXN+1][LOG+1];
int lg[2*MAXN+1];
int ne;
void Euler(int nod){
    int i;
    ne++;
    euler[ne]=nod;
    first[nod]=ne;
    for(i=0;i<G[nod].size();i++)
      if(lvl[G[nod][i].nod]>lvl[nod]){
         Euler(G[nod][i].nod);
         ne++;
         euler[ne]=nod;
      }
}
struct Dinamic{
    int val;
    int nod;
};
Dinamic dp[MAXN+1][LOG+1];
inline int getmax(int a,int b){
   if(a<b) return b;
   return a;
}
inline int Road(int nod,int conf){
    int max,log;
    max=log=0;
    while((1<<log)<=conf){
       if((1<<log)&conf){
          max=getmax(max,dp[nod][log].val);
          nod=dp[nod][log].nod;
       }
       log++;
    }
    return max;
}
int main(){
   FILE*fi,*fout;
   int n,m,k,i,j,x,y,lca,a,b,log,depth,p1,p2;
   fi=fopen("radiatie.in" ,"r");
   fout=fopen("radiatie.out" ,"w");
   fscanf(fi,"%d %d %d  " ,&n,&m,&k);
   for(i=1;i<=m;i++)
      fscanf(fi,"%d %d %d " ,&V[i].a,&V[i].b,&V[i].c);
   std::sort(V+1,V+m+1);
   for(i=1;i<=m;i++)
      if(myfind(V[i].a)!=myfind(V[i].b)){
         myunion(V[i].a,V[i].b);
         add_Edge(V[i].a,V[i].b,V[i].c);
         add_Edge(V[i].b,V[i].a,V[i].c);
      }
   lvl[ROOT]=1;
   DFS(ROOT);
   ne=0;
   Euler(ROOT);
   lg[1]=0;
   for(i=2;i<=ne;i++)
      if((i-1)&i)
        lg[i]=lg[i-1];
      else
        lg[i]=lg[i-1]+1;
   for(i=1;i<=ne;i++)
      rmq[i][0]=euler[i];
   for(log=1;(1<<log)<=ne;log++)
    for(i=1;i+(1<<log)<=ne+1;i++){
       a=rmq[i][log-1];
       b=rmq[i+(1<<(log-1))][log-1];
       if(lvl[a]<lvl[b])
         rmq[i][log]=a;
       else
         rmq[i][log]=b;
    }
   depth=0;
   for(i=1;i<=n;i++)
     if(lvl[i]>depth)
       depth=lvl[i];
   for(i=1;i<=n;i++)
    for(j=0;j<G[i].size();j++)
     if(lvl[i]>lvl[G[i][j].nod]){
        dp[i][0].nod=G[i][j].nod;
        dp[i][0].val=G[i][j].val;
     }
   for(log=1;(1<<log)<=depth;log++)
    for(i=1;i<=n;i++){
       dp[i][log].nod=dp[dp[i][log-1].nod][log-1].nod;
       dp[i][log].val=getmax(dp[i][log-1].val,dp[dp[i][log-1].nod][log-1].val);
    }
   while(k>0){
      k--;
      fscanf(fi,"%d %d " ,&x,&y);
      if(first[x]<first[y]){
         log=lg[first[y]-first[x]+1];
         p1=first[x];
         p2=first[y];
      }
      else{
         log=lg[first[x]-first[y]+1];
         p1=first[y];
         p2=first[x];
      }
      a=rmq[p1][log];
      b=rmq[p2-(1<<log)+1][log];
      if(lvl[a]<lvl[b])
         lca=a;
      else
         lca=b;
      fprintf(fout,"%d\n" ,getmax(Road(x,lvl[x]-lvl[lca]),Road(y,lvl[y]-lvl[lca])));
   }
   fclose(fi);
   fclose(fout);
   return 0;
}