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\)之间的最短路. 思路 由于边数最多只比 ...
随机推荐
- Mysql 忘记 root密码解决
1 stop mysql Ubuntu/Debian: sudo /etc/init.d/mysql stop CentOs: sudo /etc/init.d/mysqld stop 2 启动saf ...
- 关于kvm虚拟机的克隆方法总结
kvm虚拟机的克隆分为两种情况,第一种kvm宿主机上对虚拟机直接克隆 第二种通过复制配置文件与磁盘文件的虚拟机复制克隆(适用于异机的静态迁移). 现笔者将分别两种kvm虚拟机克隆的的详细操作过程都记录 ...
- 【CF870F】Paths 分类讨论+数学
[CF870F]Paths 题意:一张n个点的图,对于点i,j(i!=j),如果gcd(i,j)!=1,则i到j有一条长度为1的无向边.令dis(i,j)表示从i到j的最短路,如果i无法到j,则dis ...
- 【CF884F】Anti-Palindromize 费用流
[CF884F]Anti-Palindromize 题意:定义一个串是反回文的,当且仅当对于1<=i<=len,$a_i!=a_{len-i+1}$. 现在给出一个长度为n的串S(n是偶数 ...
- jfinal的model和record如何相互转化?
一.model转record: Model类: 1. /** * Convert model to record. */public Record toRecord() { return new Re ...
- Zabbix忘记登录密码重置
Zabbix忘记登录密码了 登录MySQL查看用户 select * from users\G 重置密码 mysql> use zabbix; mysql> update users se ...
- hdu2896 病毒肆虐【AC自动机】
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- nowcoder2018年全国多校算法寒假训练营练习比赛(第一场)
[气死我了 写完了博客发布 点看来一看怎么只剩下一半不到的内容了!!!!!!!!!!] [就把卡的那两道放上来好了 其余的不弄了 生气!!!!!] 可以说是很久没有打比赛了 今天这一场主要是 基础算 ...
- ECharts修改坐标轴,坐标轴字体,坐标轴网格样式以及控制坐标轴是否显示
转自:http://blog.csdn.net/kirinlau/article/details/72876689 首先要将一个图表显示在前端页面上: var myChart = echarts.in ...
- arcgis server multipoint 服务 applyedit功能
首先打开arcmap,在catalog中新建 File GDB 在File GDB 中新建 Feature Class 类型选择 Multipoint 选择坐标 此时图层列表中有了新建的要素,点击Ed ...