• 货车运输


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

    看代码:

    #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
    ",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
    ",val[lca(x,y)]);
        }
        return 0;
    }

    深深地感到自己的弱小。

  • 相关阅读:
    Vijos P1597 2的幂次方【进制+递归】
    NUC1100 Biorhythms【中国剩余定理】
    HDU1370 Biorhythms【中国剩余定理】
    NUC1090 Goldbach's Conjecture【哥德巴赫猜想 】
    NUC1305 哥德巴赫猜想
    剑指Offer——最小的K个数
    剑指Offer——数组中出现次数超过一半的数字
    剑指Offer——字符串的排列
    剑指Offer——二叉搜索树与双向链表
    剑指Offer——复杂链表的复制
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12510665.html
Copyright © 2020-2023  润新知