货车运输

重构树的版子题,当然也可以用倍增或二分答案。

看代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
struct node{
    int x,y,z;
}edge[maxn];
int n,m,q,cnt;
inline int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*f;
}
inline int cmp(node x,node y){
    return x.z>y.z;
}
int fa[maxn],f[maxn],val[maxn];
inline int find1(int x){
    if(x==fa[x])return x;
    return fa[x]=find1(fa[x]);
}
inline int find2(int x){
    if(x==f[x])return x;
    return f[x]=find2(f[x]);
}
int beg[maxn],nex[maxn],to[maxn],e;
inline void add(int x,int y){
    e++;nex[e]=beg[x];
    beg[x]=e;to[e]=y;
}
int dep[maxn],ff[maxn][20];
inline void dfs(int x,int anc){
    dep[x]=dep[anc]+1;
    ff[x][0]=anc;
    for(int i=1;i<=19;i++)
        ff[x][i]=ff[ff[x][i-1]][i-1];
    for(int i=beg[x];i;i=nex[i])
        if(to[i]!=anc)dfs(to[i],x);
}
inline int lca(int x,int y){
    if(dep[x]<dep[y])swap(x,y);
    for(int i=19;i>=0;i--)
        if(dep[x]-(1<<i)>=dep[y])
            x=ff[x][i];
    if(x==y)return x;
    for(int i=19;i>=0;i--)
        if(ff[x][i]!=ff[y][i]){
            x=ff[x][i];
            y=ff[y][i];
        }
    return ff[x][0];
}
int main(){
    cnt=n=read();m=read();
    for(int i=1;i<=m;i++){
        edge[i].x=read();
        edge[i].y=read();
        edge[i].z=read();
    }
    sort(edge+1,edge+1+m,cmp);
    for(int i=1;i<=2*n;i++)
        fa[i]=f[i]=i;
    int x,y;
    for(int i=1;i<=m;i++){
        x=edge[i].x,y=edge[i].y;
        if(find1(x)!=find1(y)){
            cnt++;
            val[cnt]=edge[i].z;
            add(cnt,find2(x));
            add(find2(x),cnt);
            add(cnt,find2(y));
            add(find2(y),cnt);
            //printf("%d %d %d\n",cnt,find2(x),find2(y));
            f[find2(x)]=f[find2(y)]=cnt;
            fa[find1(x)]=find1(y);
        }
    }
    for(int i=1;i<=cnt;i++)
        if(f[i]==i)dfs(i,0);
    q=read();
    for(int i=1;i<=q;i++){
        x=read(),y=read();
        if(find1(x)!=find1(y))puts("-1");
        else printf("%d\n",val[lca(x,y)]);
    }
    return 0;
}

深深地感到自己的弱小。

posted @ 2020-03-17 14:48  syzf2222  阅读(106)  评论(0编辑  收藏  举报