uva11354 LCA+最小生成树+dp
源自大白书
题意 有n座城市通过m条双向道路相连,每条道路都有一个危险系数。你的任务是回答若干个询问,每个询问包含一个起点s和一个终点t,要求找到一条从s到t的路,使得途径所有的边的大最大危险系数最小。
解: 首先求出最小生成树,并把它改写成有根树,让fa[i]和cost[i]分别表示节点i的父亲编号和它与父亲之间的边权,L[i]表示节点i的深度,接下来通过预处理计算出数组anc 和 maxcost 其中anc[i][j] 表示节点i的2^j 级祖先的编号 macost[i][j] 表示i到2^j级 祖先之间的最大权值。
有了预处理 私用LCA 来查询结果, 查询p,q, 并且p比q深, 则可以先把p提升到和q处于同一级的位置,然后用二进制展开的方法不断把p和q同时往上提(保证二者深度相等),同时更新最大的边权
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string.h>
#include <vector>
using namespace std;
const int maxn = +;
const int INF =;
struct Edge{
int from,to, dist;
bool operator <(const Edge & rhs)const{
return dist<rhs.dist;
}
}E[maxn*];
struct ed{
int to,dist;
};
vector<ed> G[maxn];
int fa[maxn],per[maxn],cost[maxn],L[maxn];
int anc[maxn][],maxcost[maxn][];
void inti(int n){
for(int i =; i<n; i++){
per[i] = i;
G[i].clear();
}
}
void preprocess( int n){
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 fid(int u){
return per[u]==u?u:(per[u]= fid(per[u]));
}
void dfs(int u, int p,int dist, int depth){
fa[u]=p; cost[u] = dist; L[u] = depth;
for(int i = ; i<(int)G[u].size(); ++i){
ed e = G[u][i];
if(e.to == p) continue;
dfs(e.to,u,e.dist,depth+);
}
}
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;
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;
}
int main()
{
int n,m,f=;
while(scanf("%d%d",&n,&m)==){
inti(n);
for(int i=; i<m ; i++){
int x,y,d;
scanf("%d%d%d",&x,&y,&d);
x--,y--;
E[i]=(Edge){x,y,d};
}
int lest = n;
sort(E,E+m);
for(int i=; i<m; i++){
int a = E[i].from,b=E[i].to, dist= E[i].dist;
int ca = fid(a),cb = fid(b);
if(ca!=cb){
per[ca] =cb;
lest--;
G[a].push_back((ed){b,dist} );
G[b].push_back((ed){a,dist} );
if(lest==) break;
}
}
dfs(,-,,);
preprocess(n);
int Q;
if(f)
puts("");
else f=;
scanf("%d",&Q);
for(int i =; i<Q; i++){
int s,t;
scanf("%d%d",&s,&t);
s--;t--;
printf("%d\n",query(s,t));
} } return ;
}
uva11354 LCA+最小生成树+dp的更多相关文章
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- hdu 4081 Qin Shi Huang's National Road System(最小生成树+dp)2011 Asia Beijing Regional Contest
同样是看别人题解才明白的 题目大意—— 话说秦始皇统一六国之后,打算修路.他要用n-1条路,将n个城市连接起来,并且使这n-1条路的距离之和最短.最小生成树是不是?不对,还有呢.接着,一个自称徐福的游 ...
- POJ3728 LCA RMQ DP
题意简述:给定一个N个节点的树,1<=N<=50000 每个节点都有一个权值,代表商品在这个节点的价格.商人从某个节点a移动到节点b,且只能购买并出售一次商品,问最多可以产生多大的利润. ...
- POJ3417 LCA+树dp
http://poj.org/problem?id=3417 题意:先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂 ...
- BZOJ3732Network——kruskal重构树+倍增+LCA/最小生成树+倍增
题目描述 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 & ...
- LCA&最小生成树
LCA 经常被用来使用.比如询问树两点之间的距离. 比如树上差分 都是经常被使用的类型.有的时候倍增求LCA的同时还可以优化算法. 这道题呢 求一个严格的最小生成树,当然如果不严格的话如果有重边那么就 ...
- Codeforces Round #343 (Div. 2) E. Famil Door and Roads lca 树形dp
E. Famil Door and Roads 题目连接: http://www.codeforces.com/contest/629/problem/E Description Famil Door ...
- POJ3728 THE MERCHANT LCA RMQ DP
题意简述:给定一个N个节点的树,1<=N<=50000 每个节点都有一个权值,代表商品在这个节点的价格.商人从某个节点a移动到节点b,且只能购买并出售一次商品,问最多可以产生多大的利润. ...
- The Shortest Statement(Educational Codeforces Round 51 (Rated for Div.2)+最短路+LCA+最小生成树)
题目链接 传送门 题面 题意 给你一张有\(n\)个点\(m\)条边的联通图(其中\(m\leq n+20)\),\(q\)次查询,每次询问\(u\)与\(v\)之间的最短路. 思路 由于边数最多只比 ...
随机推荐
- 深入浅出WPF之Binding的使用(一)
在WPF中Binding可以比作数据的桥梁,桥梁的两端分别是Binding的源(Source)和目标(Target).一般情况下,Binding源是逻辑层对象,Binding目标是UI层的控件对象:这 ...
- linux系统中关于shell变量$*与$@的区别
在我们初学linux系统shell时,可能会感觉$@与$*没什么区别,如下面shell脚本: #!/bin/bash# name:a.sh # echo 'this script $* is: '$* ...
- Coding 代码管理快速入门(转)
当项目创建好了之后,我们该如何上传代码到 coding 上呢? Coding 网站使用“ Git 仓库”(类似 github )来管理代码. 其操作原理在于:利用 git 服务,将本地的项目目录下的文 ...
- 几种在Linux下查询外网IP的办法(转)
Curl 纯文本格式输出: curl icanhazip.com curl ifconfig.me curl curlmyip.com curl ip.appspot.com curl ipinfo. ...
- Pointer Lock
Pointer Lock API 指针锁定(以前叫做 鼠标锁定) 提供了一种输入方法,这种方法是基于鼠标随着时间推移的运动的(也就是说,deltas),而不仅是鼠标光标的绝对位置.通过它可以访问原始的 ...
- Java--static、final、static final的区别
一.final final修饰类:表示该类不能被继承:final类中的方法默认是final的: final修饰方法:表示该方法无法被重写: final修饰方法参数:表示在变量的生存期中它的值不能被改变 ...
- IE 兼容一问题一小记
记录一下上一周做的一个门户网站!因为兼容问题折腾了我一天时间,今天有空了就把其中坑记录一下! 1.轮换效果不能显示出1.2.3... (ie7不行,大于ie7的可以),原因就是因为,js对象的最一个个 ...
- HOJ 2133&POJ 2964 Tourist(动态规划)
Tourist Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1503 Accepted: 617 Description A ...
- SequenceFile实例操作
HDFS API提供了一种二进制文件支持,直接将<key,value>对序列化到文件中,该文件格式是不能直接查看的,可以通过hadoop dfs -text命令查看,后面跟上Sequen ...
- codeforces 761D - Dasha and Very Difficult Problem
time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...