zoukankan      html  css  js  c++  java
  • bzoj3732

    给你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 < = 20,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

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

    Sample Input

    6 6 8
    1 2 5
    2 3 4
    3 4 3
    1 4 8
    2 5 7
    4 6 2
    1 2
    1 3
    1 4
    2 3
    2 4
    5 1
    6 2
    6 1

    Sample Output

    5
    5
    5
    4
    4
    7
    4
    5

    HINT

    1 <= N <= 15,000 

    1 <= M <= 30,000 

    1 <= d_j <= 1,000,000,000 

    1 <= K <= 15,000

    模拟一下样例,发现最小生成树贼有道理
    然后倍增求树上最大值,感觉树剖也行
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxn 15005
    #define maxm 30005
    using namespace std;
    struct note{
        int u,v,c;
        friend bool operator<(note a,note b)
        {
            return a.c<b.c;
        }
    }edge[maxm];
    int to[maxm<<1],head[maxn],val[maxm<<1],next[maxm<<1];
    int f[maxn][20],g[maxn][20],dep[maxn];
    int rep[maxn];
    int num,cnt,n,m,k;
    int getrep(int x)
    {
        if(rep[x]==x) return x;
        return rep[x]=getrep(rep[x]);
    }
    void dfs(int u,int fa)
    {
        for(int edge=head[u];edge;edge=next[edge])
        {
            if(to[edge]==fa) continue;
            f[to[edge]][0]=u;
            g[to[edge]][0]=val[edge];
            dep[to[edge]]=dep[u]+1;
            dfs(to[edge],u);
        }
    }
    void go_up(int &x,int c)
    {
        c=-c;
        for(int i=0;i<=19;i++)
        if(c&(1<<i)) cnt=max(cnt,g[x][i]),x=f[x][i];
    }
    void make_lca()
    {
        for(int j=1;j<=19;j++)
            for(int i=1;i<=n;i++)
            {
                if(f[i][j-1])
                { 
                    f[i][j]=f[f[i][j-1]][j-1];
                    g[i][j]=max(g[i][j-1],g[f[i][j-1]][j-1]);
                }
                else f[i][j]=0;
            }    
    }
    int lca(int x,int y)
    {
        if(dep[x]>dep[y]) go_up(x,dep[y]-dep[x]);
        else go_up(y,dep[x]-dep[y]);
        if(x==y) return cnt;
        for(int i=19;i>=0;i--)
        if(f[x][i]!=f[y][i])
        {
            cnt=max(cnt,max(g[x][i],g[y][i])); 
            x=f[x][i];y=f[y][i];   
         } 
         return max(cnt,max(g[x][0],g[y][0]));  
    }
    void add(int u,int v,int c)
    {
        to[++num]=v;
        val[num]=c;
        next[num]=head[u];
        head[u]=num;
    }
    int main()
    {
        scanf("%d %d %d",&n,&m,&k);
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].c);
        }
        sort(edge+1,edge+1+m);
        for(int i=1;i<=n;i++) rep[i]=i;
        for(int i=1;i<=m;i++)
        if(getrep(edge[i].u)!=getrep(edge[i].v))
        {
            rep[getrep(edge[i].u)]=getrep(edge[i].v);
            add(edge[i].u,edge[i].v,edge[i].c);
            add(edge[i].v,edge[i].u,edge[i].c);        
        }
        
        dfs(1,0);
        make_lca();
        while(k--)
        {
            int x,y;
            scanf("%d %d",&x,&y);
            cnt=0;
            printf("%d
    ",lca(x,y));
        }
        return 0;
    } 
  • 相关阅读:
    vue-cli webpack3扩展多模块打包
    性能对比:aelf智能合约运行环境性能是evm的1000倍
    aelf帮助C#工程师10分钟零门槛搭建DAPP&私有链开发环境
    ASP.NET Core依赖注入最佳实践,提示&技巧
    linux环境安装php fileinfo扩展
    简单的部署nodejs和web应用
    安卓NDK操作sqlite3
    [解决]微信小程序调用wx.login解密之后出现乱码的问题
    windows server 2008 iis 添加ssl证书
    Mac 下修改文件或文件夹的隐藏状态
  • 原文地址:https://www.cnblogs.com/dancer16/p/7705518.html
Copyright © 2011-2022 走看看