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 ...
随机推荐
- How to only capute sub-matched character by grep
File content: <a href="ceph-0.80.9-82.1.x86_64.rpm"><img src="/icons/rpm.gif ...
- 利用nodeJS实现的网络小爬虫
var http=require("http");var cheerio=require('cheerio');var url="http://www.imooc.com ...
- NOI上看到的几个小学奥数
:余数相同问题 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 已知三个正整数 a,b,c. 现有一个大于1的整数x,将其作为除数分别除a,b,c,得到的余数相同 ...
- Corex-M0 系统嘀嗒定时器 Systick 详解
- 我的jsonp跨域问题
关于jsonp跨域问题,在这个方面也是了解一点点,先记录下来,主要作为以后查看,之前下载并安装过wampserver,了解到了jsonp和json的区别,现在谈谈跨域这个问题: 首先什么是跨域,简单地 ...
- Windbg调试命令详解
作者:张佩][原文:http://www.yiiyee.cn/Blog] 1. 概述 用户成功安装微软Windows调试工具集后,能够在安装目录下发现四个调试器程序,分别是:cdb.exe.ntsd. ...
- .net使用pdfobject.js加载pdf文件
1.下载pdfobject.js文件 2. <script type="text/javascript" src="<%= Application[" ...
- 你知道吗?使用任何HTML5开发工具都可开发iOS、Android原生App
APICloud App开发平台一直在不断升级开发工具库,这一年增加了众多开发工具.目的就是让开发者可以选择使用任何自己喜欢的HTML5开发工具去开发App.这次,APICloud把所有关于开发工具的 ...
- MyBatis操作指南-与Spring集成(基于注解)
- docker 组件(c/s)
Docker 组件 1. docker client : docker的客户端 2. docker server : docker daemon的主要组成部分,接受用户通过docker client发 ...