题目链接:https://vjudge.net/contest/144221#problem/B

题意:找一条从 s 到 t  的路,使得瓶颈路最小。

点的数目是10^4,如果向之前的方案求 maxcost数组,O(n*n)时间是过不了的,这个时候,用到了增倍祖先。

关于倍增祖先:http://m.w2bc.com/article/177601

我要补充的是,倍增祖先的优点,是在于倍增,他写的案例,没有体现出倍增,这里强调一下。有点像二分的思想;

利用倍增祖先初始化maxcost[i][j]数组,maxcost[i][j] 在倍增祖先里面表示的,结点 i 的第2j级祖先之间的瓶颈。

用O(nlogn)初始化,然后,查询是O(logn)。

#include <bits/stdc++.h>
using namespace std; const int maxn = + ;
const int INF = 0x3f3f3f3f;
const int logmaxn = ; int n,m; struct Edge
{
int u,v,d;
bool operator < (const Edge& rhs) const
{
return d < rhs.d;
}
}; Edge e[maxn]; int pa[maxn]; int Find_Set(int x)
{
if(x!=pa[x])
pa[x] = Find_Set(pa[x]);
return pa[x];
} vector<int> G[maxn],C[maxn]; struct LCA
{
int n;
int fa[maxn];
int cost[maxn];
int L[maxn];
int anc[maxn][logmaxn];
int maxcost[maxn][logmaxn]; void preprocess()
{
for(int i=; i<n; i++)
{
anc[i][] = fa[i];
maxcost[i][] = cost[i];
for(int j=; (<<j)<n; j++)
anc[i][j] = -;
} for(int j=; (<<j)<n; j++)
{
for(int i=; i<n; i++)
{
if(anc[i][j-]!=-)
{
int a = anc[i][j-];
anc[i][j] = anc[a][j-];
maxcost[i][j] = max(maxcost[i][j-],maxcost[a][j-]);
}
}
}
} int query (int p,int q)
{
int log;
if(L[p]<L[q]) swap(p,q);
for(log=; (<<log)<=L[p]; log++);
log--; int ans = -INF;
for(int i=log; i>=; i--)
{
if(L[p]-(<<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>=; i--)
{
if(anc[p][i]!=-&&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; void dfs(int u,int fa,int level)
{
solver.L[u] = level;
for(int i=; i<G[u].size(); i++)
{
int v = G[u][i];
if(G[u][i]!=fa)
{
solver.fa[v] = u;
solver.cost[v] = C[u][i];
dfs(G[u][i],u,level+);
}
}
} int main()
{
//freopen("in.txt","r",stdin);
int kase = ;
while(scanf("%d%d",&n,&m)==&&n)
{
for(int i=; i<m; i++)
{
int u,v,d;
scanf("%d%d%d",&u,&v,&d);
u--;
v--;
e[i] = (Edge)
{
u,v,d
};
}
sort(e,e+m); for(int i=; i<n; i++)
{
pa[i] = i;
G[i].clear();
C[i].clear();
} for(int i=; i<m; i++)
{
int u = e[i].u;
int v = e[i].v;
int fx = Find_Set(u);
int fy = Find_Set(v); if(fx!=fy)
{
pa[fx] = fy;
G[u].push_back(v);
C[u].push_back(e[i].d);
G[v].push_back(u);
C[v].push_back(e[i].d);
}
}
solver.n = n;
dfs(,-,);
solver.preprocess();
if(kase++!=)
puts("");
int Q;
scanf("%d",&Q);
while(Q--)
{
int u,v;
scanf("%d%d",&u,&v);
u--;
v--;
printf("%d\n",solver.query(u,v));
} } return ;
}

Uva 11354 LCA 倍增祖先的更多相关文章

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

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

  2. 洛谷 3379 最近公共祖先(LCA 倍增)

    洛谷 3379 最近公共祖先(LCA 倍增) 题意分析 裸的板子题,但是注意这题n上限50w,我用的边表,所以要开到100w才能过,一开始re了两发,发现这个问题了. 代码总览 #include &l ...

  3. CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先)

    CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先) 题意分析 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天, ...

  4. LCA(最近公共祖先)——LCA倍增法

    一.前人种树 博客:最近公共祖先 LCA 倍增法 博客:浅谈倍增法求LCA 二.沙场练兵 题目:POJ 1330 Nearest Common Ancestors 代码: const int MAXN ...

  5. Bond UVA - 11354(LCA应用题)

    Once again, James Bond is on his way to saving the world. Bond's latest mission requires him to trav ...

  6. LCA倍增算法

    LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...

  7. LCA(倍增在线算法) codevs 2370 小机房的树

    codevs 2370 小机房的树 时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点, ...

  8. POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)

    1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...

  9. 【codevs2370】小机房的树 LCA 倍增

    2370 小机房的树  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0 ...

随机推荐

  1. 如何在springMVC 中对REST服务使用mockmvc 做测试

    如何在springMVC 中对REST服务使用mockmvc 做测试 博客分类: java 基础 springMVCmockMVC单元测试  spring 集成测试中对mock 的集成实在是太棒了!但 ...

  2. Centos minimal安装

    Q:为什么要安装minimal版本?而不是完整版 A:因为它资源小啊 @ @ 怎么安装就不说了,网上资源大把,Centos7好像变化挺大,mysql都装不上,还是装6吧~ 1.安装完是不能联网的,解决 ...

  3. Virtualbox虚拟机配置CentOS7.0静态网络

    1.首先在Virtualbox下将网络设置为Bridged Adapter,此项设置可以使本机与虚拟机进行互访,而NAT模式只能进行单项访问: 2.先切换到root,配置网卡信息需要用到root,然后 ...

  4. .NET Core Analysis

    .NET Core 1.0.1 Module Component .NET Core MongoDB MongoDB.Driver There has a nuget package availabl ...

  5. Django根据现有数据库建立model

    Django引入外部数据库还是比较方便的,步骤如下 创建一个项目,修改seting文件,在setting里面设置你要连接的数据库类型和连接名称,地址之类,和创建新项目的时候一致 运行下面代码可以自动生 ...

  6. web 安全的前期准备哦

    学习web安全  需要的软件  和 基础 基础会在以后发出来  软件  在网上都可以下 首先   你要有一款虚拟机软件 虚拟系统通过生成现有操作系统的全新虚拟镜像,它具有真实windows系统完全一样 ...

  7. java方法与构造

    public class StaticClass { static int i = 50; int y; // 构造只能有访问修饰符public.protected.private 修饰 (访问修饰符 ...

  8. html5开发移动页面去掉点击出现的透明阴影----&&-----元素垂直居中

    [摘要:做好的页里正在脚机端测试时,发明局部扫瞄器,tap后会涌现一个半通明的灰色配景,(被批...),起先认为是outline作祟,减上后发明出反映,末了发明是tap后的配景下明,要重设那个]   ...

  9. c# 利用动态库DllImport("kernel32")读写ini文件(提供Dmo下载)

    c# 利用动态库DllImport("kernel32")读写ini文件 自从读了设计模式,真的会改变一个程序员的习惯.我觉得嘛,经验也可以从一个人的习惯看得出来,看他的代码编写习 ...

  10. STL—Vector简介

    有关C++ STL 中的vector向量的用法(代码示例) 一. 简介 Vector是一个称为向量的顺序容器(不明白顺序容器与关联容器的可以Google). 二. 特点 1. 动态(相当于一个动态数组 ...