Cod sursa(job #2396089)

Utilizator ApetriiRaduApetrii Radu ApetriiRadu Data 3 aprilie 2019 11:02:23
Problema Radiatie Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.77 kb
#include <bits/stdc++.h>
#define NMAX 15005
#define LMAX 20
#define INF INT_MAX/2
#define pb push_back

using namespace std;

ifstream fin("radiatie.in");
ofstream fout("radiatie.out");


struct numestecumdoresti{
    int x,val;
};
int cmin[NMAX],vfmin[NMAX];
bool operator<(numestecumdoresti x,numestecumdoresti y){
    return x.val>y.val;
}
priority_queue <numestecumdoresti> coada;

struct graf{int vf,cost;};
vector<graf> G[NMAX];
vector<graf> A[NMAX];
int tata[NMAX];
int M[2*NMAX][LMAX];
int n,m,query;
int euler[2*NMAX],lg;
int level[2*NMAX];
int ind[NMAX];
int dist[NMAX];
int h[NMAX];
bool uz[NMAX];

bool uz2[NMAX];

void citire();
void dfs(int x);
void constr();
void rezolv();
void initializare();
void prim();
int main()
{int i,start=1;
 citire();
 initializare();
 prim();
 dfs(start);
 constr();
 rezolv();
 return 0;
}
void citire()
{int i,x,y,cost;
 fin>>n>>m>>query;
 for(i=1;i<=m;i++)
    {fin>>x>>y>>cost;
     G[x].pb({y,cost});
     G[y].pb({x,cost});
    }
}
void dfs(int x)
{int i;
 uz[x]=1;
 lg++;
 euler[lg]=x;
 level[lg]=h[x];
 if(!ind[x])
    ind[x]=lg;
 for(i=0;i<A[x].size();i++)
    if(!uz[A[x][i].vf])
      {h[A[x][i].vf]=h[x]+1;
       //dist[A[x][i].vf]=dist[x]+A[x][i].cost;
       /*if(dist[x]>A[x][i].cost)
          dist[A[x][i].vf]=dist[x];
          else
            dist[A[x][i].vf]=A[x][i].cost;*/
       dist[A[x][i].vf]=A[x][i].cost;
       dfs(A[x][i].vf);
       lg++;
       euler[lg]=x;
       level[lg]=h[x];
      }
}
void constr()
{int i,j;
for(i=1;i<=2*n-1;i++)
    M[i][0]=i;
for(j=1;(1<<j)<=2*n-1;j++)
    for(i=1;i+(1<<j)<=2*n-1;i++)
       if(level[M[i][j-1]] < level[M[i+(1<<(j-1))][j-1]])
          M[i][j]=M[i][j-1];
          else
            M[i][j]=M[i+(1<<(j-1))][j-1];
}
void rezolv()
{int i,k,x,y,lca,nod1,nod2,d1,d2;
 for(i=1;i<=query;i++)
    {fin>>x>>y;
     nod1=x;
     nod2=y;
     x=ind[x];
     y=ind[y];
     if(x<y)
        swap(x,y);
     k=log2(x-y+1);
     if(level[M[y][k]] < level[M[x-(1<<k)+1][k]])
        lca=euler[M[y][k]];
        else
            lca=euler[M[x-(1<<k)+1][k]];
      d1=0;
      d2=0;
      while(nod1!=lca)
           {if(d1<dist[nod1])
              d1=dist[nod1];
            nod1=vfmin[nod1];
           }
      while(nod2!=lca)
           {if(d2<dist[nod2])
              d2=dist[nod2];
            nod2=vfmin[nod2];
           }
        /*distanta=max(dist[nod1]-dist[euler[M[y][k]]],dist[nod2]-dist[euler[M[y][k]]]);
        else
            distanta=max(dist[nod1]-dist[euler[M[x-(1<<k)+1][k]]],dist[nod2]-dist[euler[M[x-(1<<k)+1][k]]]);*/
      fout<<max(d1,d2)<<'\n';
    }
}
void initializare()
{int start=1,i,minim=INT_MAX/2,varf=0;
 uz2[start]=1;
 for(i=1;i<=n;i++)
    if(i!=start)
      {cmin[i]=INF;
       //coada.push({i,cmin[i]});
      }
 for(i=0;i<G[start].size();i++)
     {cmin[G[start][i].vf]=G[start][i].cost;
      coada.push({G[start][i].vf,cmin[G[start][i].vf]});
      if(cmin[G[start][i].vf]<minim)
        {//minim=cmin[G[start][i].vf];
         varf=G[start][i].vf;
        }
     }
 //coada.push({varf,cmin[varf]});
 for(i=1;i<=n;i++)
    if(i!=start)
      vfmin[i]=start;
      else
        vfmin[i]=0;
}
void prim()
{int i,j,nod;
 while(!coada.empty())
      {nod=coada.top().x;
       coada.pop();
       if(!uz2[nod])
           {uz2[nod]=1;
           for(j=0;j<G[nod].size();j++)
              if(!uz2[G[nod][j].vf] && G[nod][j].cost<cmin[G[nod][j].vf])
                {cmin[G[nod][j].vf]=G[nod][j].cost;
                 coada.push({G[nod][j].vf,cmin[G[nod][j].vf]});
                 vfmin[G[nod][j].vf]=nod;
                }
           }
      }
 for(i=2;i<=n;i++)
    {A[i].pb({vfmin[i],cmin[i]});
     A[vfmin[i]].pb({i,cmin[i]});
    }
}