zoukankan      html  css  js  c++  java
  • bzoj3732 NetWork

    Description

    给你N个点的无向图 (1 <= N <= 15,000),记为:1…N。
    图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 < = d_j < = 1,000,000,000).

    现在有 K个询问 (1 < = K < = 15,000)。
    每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

    Input

    第一行: N, M, K。
    第2..M+1行: 三个正整数:X, Y, and D (1 <= X <=N; 1 <= Y <= N). 表示X与Y之间有一条长度为D的边。
    第M+2..M+K+1行: 每行两个整数A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

    Output

     对每个询问,输出最长的边最小值是多少。

    求出最小生成树并用树链剖分维护

    查询时查找最小生成树上A,B两点间路径上的最大值

    时间复杂度O(Klog2N)

    #include<cstdio>
    #include<vector>
    #include<algorithm>
    int n,m,k,p1,p2,p3;
    struct edge{
        int from,to,w;
        edge(){}
        edge(int a,int b,int c){
            from=a;to=b;w=c;
        }
    };
    struct edge1{
        int to,w;
        edge1(int b,int c){
            to=b;w=c;
        }
    };
    bool operator<(edge a,edge b){
        return a.w<b.w;
    }
    int ms[15003];
    int pa[15005],top[15005],sz[15005],dep[15005],son[15005],el[15005],id[15005],idp=1;
    inline int getp(int a){
        while(a^ms[a])a=ms[a];
        return a;
    }
    inline bool merge(int a,int b){
        int c=getp(a),d=getp(b);
        if(c==d)return false;
        ms[c]=d;
        while(ms[a]^d)c=ms[a],ms[a]=d,a=c;
        while(ms[b]^d)c=ms[b],ms[b]=d,b=c;
        return true;
    }
    int tr[32769];
    edge es[60001];
    std::vector<edge1> vs[15005];
    int ep=0;
    int dfs1(int w,int pa1,int dp){
        pa[w]=pa1;
        sz[w]=1;
        dep[w]=dp;
        for(int i=vs[w].size()-1,u;i>=0;i--){
            if((u=vs[w][i].to)==pa1)continue;
            sz[w]+=dfs1(u,w,dp+1);
            if(!son[w])son[w]=u;
            else if(sz[u]>sz[son[w]])son[w]=u;
        }
    }
    int dfs2(int w,int tp,int wv){
        id[w]=idp++;
        el[id[w]]=wv;
        top[w]=tp;
        for(int i=vs[w].size()-1,u;i>=0;i--){
            if((u=vs[w][i].to)==pa[w])continue;
            if(u==son[w])dfs2(u,tp,vs[w][i].w);
        }
        for(int i=vs[w].size()-1,u;i>=0;i--){
            if((u=vs[w][i].to)==pa[w])continue;
            if(u==son[w])continue;
            dfs2(u,u,vs[w][i].w);
        }
    }
    inline int max(int a,int b){return a>b?a:b;}
    inline void setv(int w,int v){
        w+=16384;
        tr[w]=v;
        for(w>>=1;w;w>>=1)tr[w]=max(tr[w+w],tr[w+w+1]);
    }
    void build(){
        for(int i=1;i<idp;i++)tr[i+16384]=el[i];
        for(int i=16383;i>0;i--)tr[i]=max(tr[i+i],tr[i+i+1]);
    }
    inline int getmax(int a,int b){
        int ans=0;
        for(a+=16383,b+=16385;a^b^1;a>>=1,b>>=1){
            if(~a&1)ans=max(ans,tr[a^1]);
            if(b&1)ans=max(ans,tr[b^1]);
        }
        return ans;
    }
    int ask(int x,int y){
        int a=top[x],b=top[y],c;
        int ans=0;
        while(a!=b){
            if(dep[a]<dep[b])c=a,a=b,b=c,c=x,x=y,y=c;
            ans=max(ans,getmax(id[a],id[x]));
            x=pa[a];
            a=top[x];
        }
        if(id[x]<id[y])setv(id[x],0),ans=max(ans,getmax(id[x],id[y])),setv(id[x],el[id[x]]);
        else setv(id[y],0),ans=max(ans,getmax(id[y],id[x])),setv(id[y],el[id[y]]);
        return ans;
    }
    int main(){
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++)ms[i]=i;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&p1,&p2,&p3);
            es[ep++]=edge(p1,p2,p3);
        }
        std::sort(es,es+ep);
        for(int i=0,a,b;i<ep;i++){
            if(merge(a=es[i].from,b=es[i].to)){
                vs[a].push_back(edge1(b,es[i].w));
                vs[b].push_back(edge1(a,es[i].w));
            }
        }
        dfs1(1,0,0);
        dfs2(1,0,0);
        build();
        for(int i=0;i<k;i++){
            scanf("%d%d",&p1,&p2);
            printf("%d
    ",ask(p1,p2));
        }
        return 0;
    }
  • 相关阅读:
    C++:变量声明和定义的关系
    Docker 方式搭建 zookeeper + kafka 集群
    Centos7.6系统下docker的安装
    CentOS7服务器下安装配置SSL
    《深入浅出密码学》|ing
    车联网入侵检测技术(持续更新)
    Hive的安装及交互方式
    Centos7中安装MySQL5.7记录
    Zookeeper-分布式锁代码实现
    【Java】String字符串的最大长度
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5135952.html
Copyright © 2011-2022 走看看