Uva 11354 LCA 倍增祖先
题目链接: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 倍增祖先的更多相关文章
- 训练指南 UVA - 11354(最小生成树 + 倍增LCA)
layout: post title: 训练指南 UVA - 11354(最小生成树 + 倍增LCA) author: "luowentaoaa" catalog: true ma ...
- 洛谷 3379 最近公共祖先(LCA 倍增)
洛谷 3379 最近公共祖先(LCA 倍增) 题意分析 裸的板子题,但是注意这题n上限50w,我用的边表,所以要开到100w才能过,一开始re了两发,发现这个问题了. 代码总览 #include &l ...
- CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先)
CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先) 题意分析 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天, ...
- LCA(最近公共祖先)——LCA倍增法
一.前人种树 博客:最近公共祖先 LCA 倍增法 博客:浅谈倍增法求LCA 二.沙场练兵 题目:POJ 1330 Nearest Common Ancestors 代码: const int MAXN ...
- Bond UVA - 11354(LCA应用题)
Once again, James Bond is on his way to saving the world. Bond's latest mission requires him to trav ...
- LCA倍增算法
LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...
- LCA(倍增在线算法) codevs 2370 小机房的树
codevs 2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点, ...
- POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)
1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...
- 【codevs2370】小机房的树 LCA 倍增
2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0 ...
随机推荐
- 有关windows系统的EXE和DLL文件说法错误
正确答案: B C 你的答案: C (错误) EXE和DLL文件都是PE文件 EXE不能有导出函数,DLL可以有导出函数 EXE有x86和x64之分,则DLL没有 EXE可以单独运行,DLL则不行 ...
- CXF调用webservice超时设置
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass(Service1Soap.cl ...
- iOS上线...踩坑
总结一下上线过程中出现的问题: 1.AppStore不允许app中出现下载别的app的提示 (例如:三方登录的时候,检测到手机未安装QQ,微信,微博,提示你的设备未安装!❌❌❌ 正确的做法:未安装的, ...
- iOS 将一串字符里面的某个字符全部标志出来
NSMutableString * mutStr = [NSMutableString stringWithString:@"aaabbbbaaaccc"]; NSString * ...
- 分享 rabbitMQ入门详解
原文地址http://blog.csdn.net/cugb1004101218/article/details/21243927 目录(?)[-] rabbitMQ说明文档 rabbitMQ是什么 消 ...
- docker 组件(c/s)
Docker 组件 1. docker client : docker的客户端 2. docker server : docker daemon的主要组成部分,接受用户通过docker client发 ...
- HBASE基础知识
HBASE的集群的搭建HBASE的表设计HBASE的底层存储模型 HBase 是一个高可靠.高性能.面向列.可伸缩的分布式缓存系统.利用HBase 技术可在廉价PC Server上搭建起大规模结构化存 ...
- The connection to adb is down, and a severe error has occured.(转)
启动android模拟器时.有时会报The connection to adb is down, and a severe error has occured.的错误.在网友说在任务管理器上把所有ad ...
- 向ES6看齐,用更好的JavaScript(一)
众所周知,JavaScript作为弱类型语言,一直是精华与糟粕共存,许多"诡异"的地方我们不得不接受并使用.其实ES6(又称ECMAScript 2015)在2015年6月就已经正 ...
- Java中对象创建过程
本文介绍的对象创建过程仅限于普通Java对象,不包括数组和Class对象. 1.类加载检查 虚拟机遇到一条new指令时,首先去检查该指令的参数能否在常量池中定位到一个类的符号引用,并且检查这个符号引用 ...