This is no different from trucking. Only the smallest spanning tree is replaced.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define MAXV 40005
#define Maxe 200005
#define MAXQ 30005
using namespace Std;
int N,M,X,Y,Z,ANC[MAXV][20],MA[MAXV][20],FATHER[MAXV],G[MAXV],H[MAXV];
int nume=0,numt=0,q;
BOOL VIS[MAXV],JUDGE[MAXV];
int DIS[MAXV];
struct Edge
{
int u,v,w,nxt;
}e[maxe],tr[maxe];
void Addedge (int u,int v,int W)
{
E[++nume].u=u;
E[nume].v=v;
E[nume].w=w;
E[nume].nxt=g[u];
G[u]=nume;
}
void Addtree (int u,int v,int W)
{
Tr[++numt].u=u;
Tr[numt].v=v;
Tr[numt].w=w;
Tr[numt].nxt=h[u];
H[U]=NUMT;
}
BOOL CMP (Edge X,edge y)
{
Return x.w<y.w;
}
int getfather (int x)
{
if (X!=father[x])
Father[x]=getfather (Father[x]);
return father[x];
}
void Unionn (int x,int y)
{
int R1=getfather (x), R2=getfather (y);
FATHER[R1]=R2;
}
void Kruskal ()
{
for (int i=1;i<=n;i++)
Father[i]=i;
for (int i=1;i<=nume*2;i++)
{
int u=e[i].u,v=e[i].v;
if (Getfather (u)!=getfather (v))
{
Addtree (U,V,E[I].W);
Addtree (V,U,E[I].W);
Unionn (U,V);
Judge[u]=true;
Judge[v]=true;
}
}
}
void Dfs (int u)
{
Vis[u]=true;
for (int i=h[u];i;i=tr[i].nxt)
{
int v=tr[i].v;
if (Vis[v]==false)
{
dis[v]=dis[u]+1;
Anc[v][0]=u;
MA[V][0]=TR[I].W;
DFS (v);
}
}
}
int LCA (int x,int y)
{
if (Dis[x]>dis[y]) swap (x, y);
for (int i=15;i>=0;i--)
{
if ((Dis[anc[y][i]]>=dis[x]) && (anc[y][i]!=0))
Y=anc[y][i];
}
for (int i=15;i>=0;i--)
{
if (Anc[x][i]!=anc[y][i])
{
X=anc[x][i];
Y=anc[y][i];
}
}
if (x==y) return x;
else return anc[x][0];
}
void work ()
{
scanf ("%d%d", &x,&y);
if ((judge[x]==false) | | | (Judge[y]==false) | | Getfather (x)!=getfather (y))
printf ("0\n");
Else
{
int R=lca (x, y);
int maxx=0;
if (x!=r)
{
for (int i=15;i>=0;i--)
{
if ((Dis[anc[x][i]]>=dis[r]) && (anc[x][i]!=0))
{
Maxx=max (Maxx,ma[x][i]);
X=anc[x][i];
}
}
}
if (y!=r)
{
for (int i=15;i>=0;i--)
{
if ((Dis[anc[y][i]]>=dis[r]) && (anc[y][i]!=0))
{
Maxx=max (Maxx,ma[y][i]);
Y=anc[y][i];
}
}
}
if (maxx==0) printf ("0\n");
else printf ("%d\n", Maxx);
}
}
int main ()
{
memset (G,0,sizeof (g));
memset (h,0,sizeof (h));
memset (vis,false,sizeof (VIS));
memset (dis,0,sizeof (dis));
memset (judge,false,sizeof (judge));
scanf ("%d%d", &n,&m);
for (int i=1;i<=m;i++)
{
scanf ("%d%d%d", &x,&y,&z);
Addedge (x, y, z);
Addedge (Y,X,Z);
}
Sort (e+1,e+2*m+1,cmp);
Kruskal ();
DFS (1);
for (int e=1;e<=15;e++)
for (int i=1;i<=n;i++)
{
ANC[I][E]=ANC[ANC[I][E-1]][E-1];
Ma[i][e]=max (ma[anc[i][e-1]][e-1],ma[i][e-1]);
}
scanf ("%d", &q);
for (int i=1;i<=q;i++)
Work ();
return 0;
}
Codevs 1519 Tolls