HDU 2887 Watering Hole(MST + 倍增LCA)
总算是做上一道LCA的应用题了...
题意:有$n$个牧场, $m$根管道分别连接编号为$u,v$的牧场花费$p_{i}$,在第$i$个牧场挖口井需要花费$w_{i}$,有$P$根管道直接连通着$u,v$,即免费连上$u,v$
对每根免费管道输出让所有牧场都有水的最小花费
先是最小生成树,用0去连每一个点,边权就是每个点的权值,然后正常建,跑一遍最小生成树,把用到的边重新建一次图,然后就对每次询问的$u,v$,减掉他们之间的路径的最长边就是答案了
因为删去这其中一条边,再免费连上$u,v$,最后还是一棵树,最小花费就减去最长边就好了。
然后求两点路径上的最长边就得用到倍增LCA,本来有点想不太明白,然后画了个图就清楚了,再预处理的dfs中,求每个点的LCA就可以直接求最长边了
$cost[u][i]$表示u往上走$2^{i}$步之间的最长边
转移就是$cost[u][i]=\max (cost[u][i-1], cost[lca[u][i-1]][i-1])$
求出来的是$u$往上走1, 2, 4, ...步的距离
如果需要往上走3步的 答案即为$max(cost[u][0], cost[lca[u][0]][1])$
这在查询过程中实现即可
#include <bits/stdc++.h>
using namespace std; inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar(); }
return x * f;
} const int N = 5e3 + ;
const int M = 3e5 + ;
struct Edge1 {
int u, v, c;
bool operator < (const Edge1 &rhs) const {
return c < rhs.c;
}
} e[N + M];
struct Edge {int v, next, c;} edge[*N];
int cnt, head[N], fa[N], lca[N][], cost[N][], dep[N], n, m, q;
bool vis[N];
inline void addedge(int u, int v, int c) {
edge[cnt].v = v; edge[cnt].c = c; edge[cnt].next = head[u]; head[u] = cnt++;
}
void init() {
cnt = ;
for (int i = ; i <= n; i++) fa[i] = i, head[i] = -, dep[i] = , vis[i] = false;
memset(cost, , sizeof(cost));
memset(lca, , sizeof(lca));
}
int getfa(int x) { return x == fa[x] ? x : fa[x] = getfa(fa[x]); } void dfs(int u) {
lca[u][] = fa[u];
vis[u] = ;
for (int i = ; i <= ; i++) {
lca[u][i] = lca[lca[u][i-]][i-];
cost[u][i] = max(cost[u][i-], cost[lca[u][i-]][i-]);
}
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v, c = edge[i].c;
if (vis[v]) continue;
dep[v] = dep[u] + ;
cost[v][] = c;
fa[v] = u;
dfs(v);
}
} int Lca(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
int ans = ;
int f = dep[u] - dep[v];
for (int i = ; i <= ; i++) {
if (f & ( << i)) {
ans = max(ans, cost[u][i]);
u = lca[u][i];
}
}
if (u == v) return ans;
for (int i = ; i >= ; i--) {
if (lca[u][i] != lca[v][i]) {
ans = max(ans, cost[u][i]);
ans = max(ans, cost[v][i]);
u = lca[u][i];
v = lca[v][i];
}
}
return max(max(ans, cost[u][]), cost[v][]);
} int main() {
while (~scanf("%d%d%d", &n, &m, &q)) {
init();
int sum = ;
int tol = ;
for (int i = ; i <= n; i++) {
int p = read();
e[++tol].u = ; e[tol].v = i; e[tol].c = p;
}
for (int i = ; i <= m; i++) {
int u = read(), v = read(), c = read();
e[++tol].u = u, e[tol].v = v, e[tol].c = c;
}
sort(e + , e + + tol);
for (int i = ; i <= tol; i++) {
int u = getfa(e[i].u), v = getfa(e[i].v);
if (u == v) continue;
fa[v] = u;
sum += e[i].c;
addedge(e[i].u, e[i].v, e[i].c);
addedge(e[i].v, e[i].u, e[i].c);
}
fa[] = ;
dfs();
while (q--) {
int u = read(), v = read();
printf("%d\n", sum - Lca(u, v));
}
}
return ;
}
HDU 2887 Watering Hole(MST + 倍增LCA)的更多相关文章
- hdu 2586 How far away ?倍增LCA
hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...
- hdu 4674 Trip Advisor(缩点+倍增lca)
花了一天半的时间,才把这道题ac= = 确实是道好题,好久没敲这么长的code了,尤其是最后的判定,各种销魂啊~ 题目中给出的条件最值得关注的就是:每个点最多只能在一个环内->原图是由一个个边连 ...
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- BFS+最小生成树+倍增+LCA【bzoj】4242 水壶
[bzoj4242 水壶] Description JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有 ...
- HDU2586 How far away? —— 倍增LCA
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 How far away ? Time Limit: 2000/1000 MS (Java/Ot ...
- 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增
倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...
- [板子]倍增LCA
倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...
- 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
随机推荐
- Tarjan求有向图强连通分量 BY:优少
Tarjan算法:一种由Robert Tarjan提出的求解有向图强连通分量的线性时间的算法. 定义给出之后,让我们进入算法的学习... [情境引入] [HAOI2006受欢迎的牛] 题目描述: 每头 ...
- Kafka理解
1. 引言 最近使用Kafka做消息队列时,完成了基本的消息发送与接收,已上线运行.一方面防止出现Bug时自己不能及时定位问题,一方面网上的配置可能还可以更加优化,决定去了解下Kafka. 2. 配置 ...
- 使用poi调整字体格式、添加单元格注释、自动调整列宽
1 创建新的工作铺 import java.io.FileOutputStream; import org.apache.poi.hssf.usermodel.HSSFCell; import org ...
- 2019 人民网java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.人民网等公司offer,岗位是Java后端开发,因为发展原因最终选择去了人民网,入职一年时间了,之前面试了很多 ...
- 在Centos6.5上部署kvm虚拟化技术
KVM是什么? KVM 全称是 基于内核的虚拟机(Kernel-based Virtual Machine),它是一个 Linux 的一个内核模块,该内核模块使得 Linux 变成了一个 Hyperv ...
- kafka汇总
Kafka 1. kafka概念 kafka是一个高吞吐亮的.分布式.基于发布/订阅(也就是一对多)的消息系统,最初由Linkedln公司开发的,使用Scala语言编写的,目前是Apache的开源项目 ...
- Django:RestFramework之-------渲染器
12.渲染器 from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer,AdminRenderer class Te ...
- 使用cmd命令行登录mysql并查看mysql状态
直接上代码,打开cmd命令窗口,进入mysql的安装目录(例如:cd D:/lnmp/bin/mysql/mysql5.7.11/bin)输入: #mysql -u root -p Enter pa ...
- react native报错处理com.android.build.api.transform.TransformException: com.android.builder.dexing.DexArchiveBuilderException: com.android.builder.dexing.DexArchiveBuilderException: Failed to process
背景:最近准备在使用react-native开发的app中接入友盟,来进行用户行为统计,分享,授权登录等操作. 在使用的过程中,遇到了一些错误信息,在此记录一下. 在修改android目录下的buil ...
- day 04 预科
目录 变量 什么是变量 变量的组成 变量名的命名规范 注释 单行注释 多行注释 turtle库的使用 今日内容 数据类型基础 变量 具体的值 存不是目的,取才是目的 为了描述世界万物的状态,因此有了数 ...