zoukankan      html  css  js  c++  java
  • gym 101081F Auction of Services 最小生成树扩展、lca树上倍增

    gym 101081F

    题意:给出一个无向图,定义一条路径的价值为 这条路径上最大的边权值。 有 Q 个询问,每次询问两个点间所有路径价值的最小值。

    tags: 最小生成树的应用。

    最小瓶颈路 :给定一个加权无向图,并给定无向图中两个结点u和v,求u到v的一条路径,使得路径上边的最大权值最小。   

    所有两个点间的最小路径价值就是在最小生成树上。 构出最小生成树后,求树上两点之间的最大边,这个倍增或树链剖分都可以解决。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 200005;
    
    int tot, head[N];
    struct Edge {
        int from, to, w, next;
        bool friend operator < (Edge a, Edge b) {
            return a.w < b.w;
        }
    } e1[N], e2[N];
    void Add(int u, int v, int w)
    {
        e2[tot]=(Edge){u,v,w,head[u] };  head[u]=tot++;
    }
    
    int n, m, q, fa[N];
    int Find(int x) { return fa[x]==x ? x : fa[x]=Find(fa[x]); }
    bool Unite(int a, int b)
    {
        int faa=Find(a), fab=Find(b);
        if(faa==fab) return false;
        else { fa[fab]=faa;  return true;  }
    }
    
    int dep[N], p[N][30], mx[N][30];
    void dfslca(int u, int fa, int w)
    {
        dep[u]=dep[fa]+1,  p[u][0]=fa,  mx[u][0]=w;
        for(int i=head[u]; i!=-1; i=e2[i].next)
            if(e2[i].to!=fa)  dfslca(e2[i].to, u, e2[i].w);
    }
    void Initlca()
    {
        mes(mx, 0);  mes(p, -1);  mes(dep, 0);  dep[0]=-1;
        dfslca(1, 0, 0);
        for(int j=1; (1<<j)<=n; ++j)
            for(int i=1; i<=n; ++i) if(p[i][j-1]!=-1)
                mx[i][j]=max(mx[i][j-1], mx[p[i][j-1]][j-1]),  p[i][j]=p[p[i][j-1]][j-1];
    }
    int solve(int a, int b)
    {
        int i, j, ans=0;
        if(dep[a] < dep[b]) swap(a, b);
        for(i=0; (1<<i)<=dep[a]; ++i) ;   --i;
        for(j=i; j>=0; --j)
            if(dep[a]-(1<<j) >= dep[b])
                ans=max(ans, mx[a][j]), a=p[a][j];
        if(a==b) return ans;
        for(j=i; j>=0; --j)
            if(p[a][j]!=-1 && p[a][j]!=p[b][j])
            {
                ans = max(ans, max(mx[a][j], mx[b][j]));
                a=p[a][j], b=p[b][j];
            }
        return ans=max(ans, max(mx[a][0], mx[b][0]));
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        mes(head, -1);  tot=0;
        rep(i,1,n) fa[i] = i;
        int u, v, w;
        rep(i,1,m)
        {
            scanf("%d%d%d", &u, &v, &w);
            e1[i] = (Edge) {u,v,w,0 };
        }
        sort(e1+1, e1+1+m);
        rep(i,1,m) if(Unite(e1[i].from, e1[i].to))
            Add(e1[i].from, e1[i].to, e1[i].w),  Add(e1[i].to, e1[i].from, e1[i].w);
        Initlca();
        scanf("%d", &q);
        rep(i,1,q)
        {
            scanf("%d%d", &u, &v);
            printf("%d
    ", solve(u, v));
        }
    
        return 0;
    }
  • 相关阅读:
    Cypress web自动化18-cypress.json文件配置baseUrl
    Linux学习29-awk提取log日志信息,统计日志里面ip访问次数排序
    docker学习14-配置 docker 阿里云/腾讯云加速器
    Cypress web自动化17-fixture加载json文件数据
    Cypress web自动化16-参数化,数据驱动测试案例
    Cypress web自动化15-Hooks使用方法
    Cypress web自动化14-window窗口属性
    Cypress web自动化13-viewport设置不同分辨率,适配不同设备,手机型号
    Cypress web自动化12-父子元素定位
    Eclipse安装scala
  • 原文地址:https://www.cnblogs.com/sbfhy/p/7520096.html
Copyright © 2011-2022 走看看