Cod sursa(job #2395792)

Utilizator ApetriiRaduApetrii Radu ApetriiRadu Data 2 aprilie 2019 21:14:33
Problema Radiatie Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.42 kb
#include <bits/stdc++.h>
#define NMAX 15005
#define LMAX 20
#define INF INT_MAX/2
using namespace std;
ifstream fin("radiatie.in");
ofstream fout("radiatie.out");

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

long long int cmin[NMAX],vfmin[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>>intrebari;
 for(i=1;i<=m;i++)
    {fin>>x>>y>>cost;
     G[x].push_back({y,cost});
     G[y].push_back({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<=intrebari;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;
 uz2[start]=1;
 for(i=1;i<=n;i++)
    if(i!=start)
      cmin[i]=INF;
 for(i=0;i<G[start].size();i++)
      cmin[G[start][i].vf]=G[start][i].cost;
 for(i=1;i<=n;i++)
    if(i!=start)
      vfmin[i]=start;
      else
        vfmin[i]=0;
}
void prim()
{int i,j,minim=INF,pozmin=1;
 for(i=1;i<=n-1;i++)
    {for(j=1;j<=n;j++)
        if(!uz2[j] && cmin[j]<minim)
          {minim=cmin[j];
           pozmin=j;
          } //pana aici am vazut pozitia minimului
     minim=INF;
     uz2[pozmin]=1;
     for(j=0;j<G[pozmin].size();j++)
        if(!uz2[G[pozmin][j].vf] && G[pozmin][j].cost<cmin[G[pozmin][j].vf])
          {cmin[G[pozmin][j].vf]=G[pozmin][j].cost;
           vfmin[G[pozmin][j].vf]=pozmin;
          }
    }
 for(i=2;i<=n;i++)
    {A[i].push_back({vfmin[i],cmin[i]});
     A[vfmin[i]].push_back({i,cmin[i]});
    }
}