比赛 中秋节快乐! 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 货车运输 最终得分 100
用户昵称 小金 运行时间 0.573 s
代码语言 C++ 内存使用 4.75 MiB
提交时间 2024-09-17 11:58:02
显示代码纯文本
#include<iostream>  
#include<cstdio>   
#include<algorithm>  
using namespace std; 
const int inf=0x3f3f3f3f;
struct Edge1{  
    int x,y,dis;
}edge1[50010];
struct Edge2{
    int to,ne,w;
}edge2[100010];
int tot,n,m,q,h[10010],d[10010],f[10010],fa[10010][21],w[10010][21]; 
bool vis[10010]; 
void add(int u,int v,int w)
{ 
    tot++;
    edge2[tot].ne=h[u];
    edge2[tot].to=v;
    edge2[tot].w=w;
    h[u]=tot;
    return ;
}
bool cmp(Edge1 x,Edge1 y)
{
    return x.dis>y.dis; 
}
int find(int x)
{
    if(f[x]==x) return f[x];
    return f[x]=find(f[x]);
}
void kruskal()
{
    sort(edge1+1,edge1+m+1,cmp); 
    for(int i=1;i<=n;i++) f[i]=i; 
    for(int i=1;i<=m;i++)
    {
        if(find(edge1[i].x)!=find(edge1[i].y))
        {
            f[find(edge1[i].x)]=find(edge1[i].y);
            add(edge1[i].x,edge1[i].y,edge1[i].dis);
            add(edge1[i].y,edge1[i].x,edge1[i].dis); 
        }
    }  
}
void dfs(int x)
{
    vis[x]=true;
    for(int i=h[x];i;i=edge2[i].ne)
    { 
        int to=edge2[i].to;
        if(vis[to]) continue;
        d[to]=d[x]+1;
        fa[to][0]=x;
        w[to][0]=edge2[i].w; 
        dfs(to);
    }
    return ;
}
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[fa[y][i]]>=d[x])
        {
            ans=min(ans,w[y][i]); 
            y=fa[y][i];
        }
    } 
    if(x==y) return ans;
    for(int i=20;i>=0;i--)
    {
        if(fa[x][i]!=fa[y][i])
        {
            ans=min(ans,min(w[x][i],w[y][i]));
            x=fa[x][i]; 
            y=fa[y][i]; 
        }
    }  
    ans=min(ans,min(w[x][0],w[y][0])); 
    return ans;
}
int main()
{
    freopen("truck.in","r",stdin);
    freopen("truck.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        edge1[i].x=x;
        edge1[i].y=y;
        edge1[i].dis=z;
    } 
    kruskal();
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        { 
            d[i]=1; 
            dfs(i);
            fa[i][0]=i;
            w[i][0]=inf;
        }
    }  
    for(int i=1;i<=20;i++)
    {
        for(int j=1;j<=n;j++)
        {
            fa[j][i]=fa[fa[j][i-1]][i-1]; 
            w[j][i]=min(w[j][i-1],w[fa[j][i-1]][i-1]);
        }
    }
    scanf("%d",&q);
    for(int i=1;i<=q;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
    return 0;
}