训练指南 UVA - 11354(最小生成树 + 倍增LCA)



layout: post
title: 训练指南 UVA - 11354(最小生成树 + 倍增LCA)
author: "luowentaoaa"
catalog: true
mathjax: true
tags:
- 最小生成树
- LCA
- 图论
- 训练指南


Bond

UVA - 11354

题意

给你一张无向图,然后有若干组询问,让你输出a->b的最小瓶颈路

题解

先求出最小生成树,然后对这个最小生成树做LCA。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e5+50;
const int logmaxn=20;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
struct LCA{
    int n;
    int fa[maxn];       ///父亲数组
    int cost[maxn];     ///和父亲的费用
    int L[maxn];        ///层次(根节点为0)
    int anc[maxn][logmaxn];     /// anc[p][i]是结点p的第2^i级父亲。anc[i][0] = fa[i]
    int maxcost[maxn][logmaxn]; /// maxcost[p][i]是i和anc[p][i]的路径上的最大费用
    void preprocess(){
        for(int i=0;i<n;i++){
            anc[i][0]=fa[i];maxcost[i][0]=cost[i];
            for(int j=1;(1<<j)<n;j++)anc[i][j]=-1;
        }
        for(int j=1;(1<<j)<n;j++)
            for(int i=0;i<n;i++)
        if(anc[i][j-1]!=-1){
            int a=anc[i][j-1];
            anc[i][j]=anc[a][j-1];
            maxcost[i][j]=max(maxcost[i][j-1],maxcost[a][j-1]);
        }
    }
    /// 求p到q的路径上的最大权
    int query(int p,int q){
        int tmp,log,i;
        if(L[p]<L[q])swap(p,q);
        for(log=1;(1<<log)<=L[p];log++);log--;
        int ans=-inf;
        for(int i=log;i>=0;i--)
        if(L[p]-(1<<i)>=L[q]){ans=max(ans,maxcost[p][i]);p=anc[p][i];}

        if(p==q)return ans; ///LCA为p

        for(int i=log;i>=0;i--)
        if(anc[p][i]!=-1&&anc[p][i]!=anc[q][i]){
            ans=max(ans,maxcost[p][i]);p=anc[p][i];
            ans=max(ans,maxcost[q][i]);q=anc[q][i];
        }
        ans=max(ans,cost[p]);
        ans=max(ans,cost[q]);
        return ans; ///LCA为fa[p](它也等于fa[q])
    }
};
LCA solver;
int pa[maxn];
int findset(int x){return pa[x]!=x?pa[x]=findset(pa[x]):x;}
vector<int>G[maxn],C[maxn];
void dfs(int u,int fa,int level){
    solver.L[u]=level;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v!=fa){
            solver.fa[v]=u;
            solver.cost[v]=C[u][i];
            dfs(v,u,level+1);
        }
    }
}

struct Edge{
    int x,y,d;
    bool operator <(const Edge& rhs)const{
        return d<rhs.d;
    }
};
const int maxm=1e5+10;
Edge e[maxm];

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int kase=0,n,m,x,y,d,Q;
    while(cin>>n>>m){
        for(int i=0;i<m;i++){
            cin>>x>>y>>d;e[i]=(Edge){x-1,y-1,d};
        }
        sort(e,e+m);
        for(int i=0;i<n;i++){pa[i]=i;G[i].clear();C[i].clear();}
        for(int i=0;i<m;i++){
            int x=e[i].x,y=e[i].y,d=e[i].d,u=findset(x),v=findset(y);
            if(u!=v){
                pa[u]=v;
                G[x].push_back(y);G[y].push_back(x);
                C[x].push_back(d);C[y].push_back(d);
            }
        }
        solver.n=n;
        dfs(0,-1,0);
        solver.preprocess();
        if(++kase!=1)cout<<endl;
        cin>>Q;
        while(Q--){
            cin>>x>>y;
            cout<<solver.query(x-1,y-1)<<endl;
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/luowentao/p/10349211.html

时间: 2024-10-12 03:11:05

训练指南 UVA - 11354(最小生成树 + 倍增LCA)的相关文章

【bzoj4242】水壶 BFS+最小生成树+倍增LCA

题目描述 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑物与原野,而且每次只能走到相邻的区域中,且不能移动到市外. JOI君因为各种各样的事情,必须在各个建筑物之间往返.虽然建筑物中的冷气设备非常好,但原野上的日光十分强烈,因此在原野上每走过一个区域都需要1单位的水.此外,原野上没有诸如自动售货机.饮水处之类的东西,因此IOI市的市民一般都携带水壶出

【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集

[题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1<=wi<=10^9. [算法]最小生成树+倍增LCA+并查集 [题解]首先求出图的一个最小生成树,则所有边分成树边和非树边. 对于非树边(u,v),假设u和v在最小生成树上的路径的最大边权Max,那么一定满足w(u,v)<=Max /////////////////////////////////////// 原文地址:https://ww

训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板)

layout: post title: 训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - Dijkstra - 图论 - 训练指南 Airport Express UVA - 11374 题意 机场快线有经济线和商业线,现在分别给出经济线和商业线的的路线,现在只能坐一站商业线,其他坐经济线,问从起点到终点的最短用时是多少,还有

训练指南 UVA - 10917(最短路Dijkstra + 基础DP)

layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - 基础DP - Dijkstra - 图论 - 训练指南 Walk Through the Forest UVA - 10917 题意 Jimmy打算每天沿着一条不同的路走,而且,他只能沿着满足如下条件的道路(A,B):存在一条从B出发回家的路径,比

训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环)

layout: post title: 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - 基础DP - BellmanFord - 图论 - 训练指南 Going in Cycle!! UVA - 11090 题意 就最小的环的平均权值 题解 分枚举平均值mid,只需判断是否存在平均值小于mid的回路,即判断是否有sum(wi)&

训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束)

layout: post title: 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - BellmanFord - 图论 - 训练指南 - 差分约束 Halum UVA - 11478 题意 带权有向图,每个点都可以有如下操作:令从ta出发的每一条边增加d,终止于ta的每一条边减小d 最后让所有边权的最小值非负且尽量大 题

训练指南 UVA - 11383(KM算法的应用 lx+ly &gt;=w(x,y))

layout: post title: 训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y)) author: "luowentaoaa" catalog: true mathjax: true tags: - KM算法 - 训练指南 Golden Tiger Claw UVA - 11383 题意 给一个n*n的矩阵,每个格子中有正整数w[i[j],试为每行和每列分别确定一个数字row[i]和col[i],使得任意格子w[i][j]<=row[i

训练指南 UVA - 11419(二分图最小覆盖数)

layout: post title: 训练指南 UVA - 11419(二分图最小覆盖数) author: "luowentaoaa" catalog: true mathjax: true tags: - 二分图 - 最小点覆盖 - 图论 - 训练指南 SAM I AM UVA - 11419 题目大意:给出一个R×C的网格,网格上棉纺了一些目标.可以在网格外发射子弹,子弹会沿着垂直或水平方向飞行,并且打掉飞行路径上的所有目标.你的任务是计算出最少需要多少子弹,各从哪个位置发射,才

【XSY2485】MST(最小生成树+倍增lca+并查集)

题面 Description 给定一个\(n\)个点\(m\)条边的连通图,保证没有自环和重边.对于每条边求出,在其他边权值不变的情况下,它能取的最大权值,使得这条边在连通图的所有最小生成树上.假如最大权值为无限大,则输出\(-1\). Input 第一行两个整数\(n\),\(m\),表示\(n\)个点\(m\)条边 接下来\(m\)行,每行\(3\)个整数\(x\),\(y\),\(z\),表示节点\(x\)和节点\(y\)之间有一条长\(z\)的边. Output 输出一行\(m\)个整数