欢迎来到SFWR的博客

P1967 货车运输

————————————————————————————————————————————————

码量巨大,几乎累死

——————————————————————————————————

#include<bits/stdc++.h>
using namespace std;
const int inf=999999999;
int n,m,ne,head[100005],f[500005],x,y,q;
int dep[100005],fa[100005][22],val[100005][22],vist[100005];
struct ned{int u,v,dis;}cn[50005];
struct node{int nxt,to,dis;}eg[100005];
int cmp(ned x,ned y){return x.dis>y.dis;}
void adde(int f,int v,int dis){eg[++ne].to=v;eg[ne].dis=dis;eg[ne].nxt=head[f];head[f]=ne;}
int find(int k){if(f[k]==k)return k;return f[k]=find(f[k]);}
void dfs(int u)
{
    vist[u]=1;
    for(int i=head[u];i;i=eg[i].nxt)
    if(!vist[eg[i].to])
    {int v=eg[i].to;
    dep[v]=dep[u]+1;val[v][0]=eg[i].dis;fa[v][0]=u;dfs(v);}  
}
int lca(int x,int y)
{    if(find(x)!=find(y))return -1;
    if(dep[x]>dep[y]) swap(x,y);
    int ans=inf;
    for(int i=20;i>=0;i--)
    if(dep[fa[y][i]]>=dep[x]){ans=min(ans,val[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(val[x][i],val[y][i]));x=fa[x][i];y=fa[y][i];}
    ans=min(ans,min(val[x][0],val[y][0]));
    return ans;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)scanf("%d%d%d",&cn[i].u,&cn[i].v,&cn[i].dis);
    sort(cn+1,cn+1+m,cmp);
    for(int i=1;i<=n;i++)f[i]=i;
    for(int i=1;i<=m;i++)
    if(find(cn[i].u)!=find(cn[i].v))
    {
        f[find(cn[i].u)]=find(cn[i].v);
        adde(cn[i].u,cn[i].v,cn[i].dis);
        adde(cn[i].v,cn[i].u,cn[i].dis);
    }
    for(int i=1;i<=n;i++)
    if(!vist[i]){dep[i]=1;val[i][0]=inf;fa[i][0]=i;dfs(i);}
    for(int i=1;i<=20;i++)
    for(int j=1;j<=n;j++){
    fa[j][i]=fa[fa[j][i-1]][i-1]; 
    val[j][i]=min(val[j][i-1],val[fa[j][i-1]][i-1]);}
    cin>>q;
    while(q--)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
}

 

posted @ 2019-06-03 21:02  SFWR  Views(115)  Comments(0Edit  收藏  举报