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 ...
随机推荐
- layui 上传图片 实现过程
layui.user一个页面只能有一个,写多了会实现js效果 上传图片官方文档有很多功能,但是演示的代码只是一个一个功能演示,如果要综合起来js代码不是简单的拼凑,需要放在指定位置,比如下面的限制文件 ...
- Spring Boot与mybatis整合
完整的项目截图 一:pom依赖 新增ojdbc6及batis-spring-boot-starter依赖 <dependency> <groupId>com.oracle< ...
- 实现一个 web 服务器
在 system1 上配置一个站点 http://system1.group8.example.com/,然后执行下述步骤: 1.从 http://server.group8.example.com/ ...
- Python与MogoDB交互
睡了大半天,终于有时间整理下拖欠的MongoDB的封装啦. 首先我们先进行下数据库的连接: conn = MongoClient('localhost',27017) # 建立连接 result = ...
- Git diff (---和+++具体解释)(转)
转自:https://blog.csdn.net/lovezbs/article/details/46492933
- 软件测试人员必备的Python知识图库
UI自动化测试(Python+Selenium等) 接口测试(Python requests等) 性能测试(Python Locust等) 安全性测试(Python Scapy等) 兼容性测试(Pyt ...
- PTA A1017
A1017 Queueing at Bank (25 分) 题目内容 Suppose a bank has K windows open for service. There is a yellow ...
- 16 doc values 【正排索引】
搜索的时候,要依靠倒排索引:排序的时候,需要依靠正排索引,看到每个document的每个field,然后进行排序,所谓的正排索引,其实就是doc values 在建立索引的时候,一方面会建立倒排索引, ...
- int转换为String,常用的四种方法。
int i = 100; 方法一:String s1 = i + " "; 方法二:String s2 = String.valueof(i); 方法三(先转换为Integer类型 ...
- redux核心知识
Provider 作用:把父组件传递进来的store对象放入react 上下文中,这样connect组件就可以从上下文中获取到store对象 Connect 作用: 1.从react上下文中取出s ...