题目链接: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. How to install starDIct on suse OS?

    1. Access page http://code.google.com/p/stardict-3/ to download starDict package or use zypper in to ...

  2. MySQL 主从配置

    mysql主从复制指两个服务器之间数据库的同步,当主服务器的数据进行了变更,从服务器也会自动更新,其过程是通过bin-log日志实现的,本质是binlog日志的传输. mysql主从分两个角色 1.主 ...

  3. Return Largest Numbers in Arrays

    题目要求 右边大数组中包含了4个小数组,分别找到每个小数组中的最大值,然后把它们串联起来,形成一个新数组. 提示:你可以用for循环来迭代数组,并通过arr[i]的方式来访问数组的每个元素. 答题思路 ...

  4. PostgreSQL windows service启动失败

    from: http://stackoverflow.com/questions/1251233/unable-to-run-postgresql-as-windows-servicepg_ctl - ...

  5. 设置默认访问项目的客户端的浏览器版本(IE版本)

    在项目开发部署中,发现浏览器不兼容现象,在不处理兼容性情况下让用户更好体验(IE浏览器) 我们来设置客户端默认访问项目的浏览器版本 如下所示的是不同IE版本下的效果截图比较: IE5.IE6下: IE ...

  6. swiper.animate~之~可以执行两种动画的升级版的Swiper Animate

        1.下载插件swiper.animate-twice.min.js,加载进页面. <!DOCTYPE html> <html> <head> ... < ...

  7. Ubuntu的安装与配置

    一.Ubuntu的安装与配置 Ubuntu 快速下载地址 1.安装VMwareTools 系统安装后,工具栏"虚拟机"-->"安装VMwareTools" ...

  8. iOS超全开源框架、项目和学习资料汇总(5)AppleWatch、经典博客、三方开源总结篇

    完整项目 v2ex – v2ex 的客户端,新闻.论坛.apps-ios-wikipedia – apps-ios-wikipedia 客户端.jetstream-ios – 一款 Uber 的 MV ...

  9. 成为一个高效的web开发人员,只需要三步

    想成为一名专业的web开发人员并不像你想象的那么容易,开发人员在开发自己的web项目时常常需要牢记很多东西,他们要不断寻找新理念,新创意,在特定时间内开发出高质量的产品,一名优秀的程序员必须明白时间的 ...

  10. rbd cache (一)

    cache 1.why The existence of cache is based on a mismatch between the performance characteristics of ...