AC通道:http://cogs.pro/cogs/problem/problem.php?pid=1439
【题解】
首先取图的最大生成树建成一棵树,然后问题就转化为了求两点到lca路径上的最小边权,用倍增处理。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
using namespace std;
#define INF 1000000000
#define MAXM 50010
#define MAXN 10010
struct node{int x,y,v;}E[MAXM];
struct node2{int y,next,v;}e[MAXN*2];
int n,m,q,len,vis[MAXN],f[MAXN],Link[MAXN],deep[MAXN],anc[MAXN][25],w[MAXN][25];
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
bool cmp(node a,node b) {return a.v>b.v;}
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
void insert(int x,int y,int v) {e[++len].next=Link[x];Link[x]=len;e[len].y=y;e[len].v=v;}
void dfs(int x)
{
vis[x]=1;
for(int i=1;i<=20;i++) {anc[x][i]=anc[anc[x][i-1]][i-1]; w[x][i]=min(w[x][i-1],w[anc[x][i-1]][i-1]);}
for(int i=Link[x];i;i=e[i].next)
if(!vis[e[i].y])
{
deep[e[i].y]=deep[x]+1;
anc[e[i].y][0]=x;
w[e[i].y][0]=e[i].v;
dfs(e[i].y);
}
}
int lca(int x,int y)
{
if(deep[x]<deep[y]) swap(x,y);
for(int i=20;i>=0;i--) if(deep[anc[x][i]]>=deep[y]) x=anc[x][i];
if(x==y) return x;
for(int i=20;i>=0;i--) if(anc[x][i]!=anc[y][i]) x=anc[x][i],y=anc[y][i];
return anc[x][0];
}
int ask(int x,int f)
{
int mn=INF;
int t=deep[x]-deep[f];
for(int i=0;i<=16;i++)if(t&(1<<i)){mn=min(mn,w[x][i]);x=anc[x][i];}
return mn;
}
int main()
{
freopen("truck.in","r",stdin);
freopen("truck.out","w",stdout);
memset(w,127/3,sizeof(w));
n=read(); m=read();
for(int i=1;i<=m;i++) {E[i].x=read(); E[i].y=read(); E[i].v=read();}
sort(E+1,E+m+1,cmp);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++)
{
int x=find(E[i].x),y=find(E[i].y);
if(x!=y)
{
f[x]=y;
insert(E[i].x,E[i].y,E[i].v);
insert(E[i].y,E[i].x,E[i].v);
}
}
for(int i=1;i<=n;i++) if(!vis[i]) dfs(i);
q=read();
for(int i=1;i<=q;i++)
{
int x=read(),y=read();
if(find(x)!=find(y)) {printf("-1\n"); continue;}
int t=lca(x,y);
printf("%d\n",min(ask(x,t),ask(y,t)));
}
return 0;
}