NOIP2013D1T3货车运输

题面
这题没什么难度 一下就能想到最大生成树上跑 L C A LCA LCA 码量也不算是太大…
不多说了直接看代码吧…

#include<bits/stdc++.h>
using namespace std;
#define reg register
#define N 10050
#define M 500050
#define QAQ puts("QAQ");
inline void read(int &x){
    
    
    int s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){
    
    s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
    x=s*w;
}
int n,m,q,x,y,tot,cnt,fa[N],dep[N],head[N],f[N][17],w[N][17];
bool vis[N];
struct nodekru{
    
    
    int st,to,val;
}e[M];
struct node{
    
    
    int to,nxt,val;
}edge[M<<1];
bool cmp(nodekru a, nodekru b){
    
    
    return a.val>b.val;
}
int find(int x){
    
    
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
inline void addedge(int u, int v, int w){
    
    
    edge[++tot].to=v,edge[tot].nxt=head[u];
    edge[tot].val=w,head[u]=tot;
}
inline void superadd(int u, int v, int w){
    
    
    addedge(u,v,w),addedge(v,u,w);
}
void kruscal(){
    
    
    sort(e+1,e+1+m,cmp);
    for(reg int i=1;i<=m;i++){
    
    
        int uu=find(e[i].st),vv=find(e[i].to);
        if(uu==vv)continue;
        fa[uu]=vv;
        superadd(e[i].st,e[i].to,e[i].val);
    }
}
void pretreat(int u, int fa){
    
    
    vis[u]=true;
    for(reg int i=1;i<=16;i++)
        f[u][i]=f[f[u][i-1]][i-1],w[u][i]=min(w[f[u][i-1]][i-1],w[u][i-1]);
    for(reg int i=head[u];i;i=edge[i].nxt){
    
    
        int vv=edge[i].to;
        if(vis[vv])continue;
        w[vv][0]=edge[i].val;
        dep[vv]=dep[u]+1;
        f[vv][0]=u;
        pretreat(vv,u);
    }
}
int lca(int x, int y){
    
    
    if(find(x)!=find(y))return -1;
    int nans=0x7f7f7f7f;    
    if(dep[x]<dep[y])swap(x,y);
    for(reg int i=16;~i;i--)if(dep[f[x][i]]>=dep[y])nans=min(nans,w[x][i]),x=f[x][i];
    if(x==y)return nans;
    for(reg int i=16;~i;i--)if(f[x][i]!=f[y][i])nans=min(nans,min(w[x][i],w[y][i])),x=f[x][i],y=f[y][i];
    return min(nans,min(w[x][0],w[y][0]));
}
int main(){
    
    
    read(n),read(m);
    for(int i=1;i<=n;i++)fa[i]=i;
    for(reg int i=1;i<=m;i++)read(e[i].st),read(e[i].to),read(e[i].val);
    kruscal();
    for(reg int i=1;i<=n;i++){
    
    
        if(!vis[i]){
    
    
            dep[i]=1;
            pretreat(i,i);
            w[i][0]=0x7f7f7f7f;
        }
    }
    read(q);
    for(reg int i=1;i<=q;i++){
    
    
        read(x),read(y);
        printf("%d\n",lca(x,y));
    }
}

猜你喜欢

转载自blog.csdn.net/dhdhdhx/article/details/102760742