P1967 货车运输
题目描述
A 国有 nn 座城市,编号从 11 到 nn,城市之间有 mm 条双向道路。每一条道路对车辆都有重量限制,简称限重。
现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
输入格式
第一行有两个用一个空格隔开的整数 n,mn,m,表示 AA 国有 nn 座城市和 mm 条道路。
接下来 mm 行每行三个整数 x, y, zx,y,z,每两个整数之间用一个空格隔开,表示从 xx 号城市到 yy 号城市有一条限重为 zz 的道路。
注意: x \neq yx =y,两座城市之间可能有多条道路 。
接下来一行有一个整数 qq,表示有 qq 辆货车需要运货。
接下来 qq 行,每行两个整数 x,yx,y,之间用一个空格隔开,表示一辆货车需要从 xx 城市运输货物到 yy 城市
输出格式
共有 qq 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。
如果货车不能到达目的地,输出 -1−1。
输入输出样例
输入 #1复制
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
输出 #1复制
3
-1
3
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int N=500005;
const int inf=0x3f3f3f3f;
int n,m,num;
int vis[N],d[N],a[N],lg[N],dis[N][31],f[N][31],head[N];
struct node{
int x,y,v;
}s[N];
struct edge{
int to,next,w;
}s1[N];
bool cmp(node x,node y){
return x.v>y.v;
}
int find(int x){
return a[x]==x?x:(a[x]=find(a[x]));
}
void add(int u,int v,int w){
s1[++num]=(edge){v,head[u],w};
head[u]=num;
}
void kruskal(){
sort(s,s+m,cmp);
int i;
for(i=1;i<=n;i++) a[i]=i;
for(i=0;i<m;i++){
int x=find(s[i].x),y=find(s[i].y);
if(x!=y){
a[x]=y;
add(s[i].x,s[i].y,s[i].v);
add(s[i].y,s[i].x,s[i].v);
}
}
}
void dfs(int x,int fa,int we){
d[x]=d[fa]+1;
f[x][0]=fa;
vis[x]=1;
dis[x][0]=we;
int i;
for(i=1;1<<i<=d[x];i++){
f[x][i]=f[f[x][i-1]][i-1];
dis[x][i]=min(dis[x][i-1],dis[f[x][i-1]][i-1]);
}
for(i=head[x];i;i=s1[i].next){
if(fa!=s1[i].to) dfs(s1[i].to,x,s1[i].w);
}
}
int lca(int x,int y){
if(find(x)!=find(y)) return -1;
int ans=inf;
if(d[x]>d[y]) swap(x,y);
for(int i=20;i>=0;i--)
// if(d[f[y][i]]>=d[x]){
if(d[y]-(1<<i)>=d[x]){
ans=min(ans,dis[y][i]);
y=f[y][i];
}
if(x==y) return ans;
for(int i=20;i>=0;i--){
if(f[x][i]!=f[y][i]){
ans=min(ans,min(dis[x][i],dis[y][i]));
x=f[x][i];
y=f[y][i];
}
}
ans=min(ans,min(dis[x][0],dis[y][0]));
return ans;
}
int main()
{
int x,y,i,j,k;
scanf("%d %d",&n,&m);
for(i=0;i<m;i++){
scanf("%d %d %d",&s[i].x,&s[i].y,&s[i].v);
}
kruskal();
for(i=1;i<=n;i++){
if(!vis[i]){
dfs(i,0,0);
}
}
/* for(i=1;i<=n;i++) lg[i]=lg[i-1]+(1<<lg[i]==i);*/
scanf("%d",&k);
while(k--){
scanf("%d %d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}