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 ...
随机推荐
- Django-11-Form组件
1. 概述 Django的Form组件一般功能有: 验证用户输入 生成html代码 返回错误信息 创建Form类 from django.shortcuts import render, redire ...
- 快速排序(Quick Sort)C语言
已知数组 src 如下: [5, 3, 7, 6, 4, 1, 0, 2, 9, 10, 8] 快速排序1 在数组 src[low, high] 中,取 src[low] 作为 关键字(key) . ...
- [终极巨坑]golang+vue开发日记【二】,登陆界面制作(一)
写在前面 本期内容是适合第一次使用vue或者golang开发的,内容会以实战的形式来讲解.看懂本段内容需要了解基础内容有html,css,最好可以看一下vue的基础.并且这里的每个知识点不可能详细解说 ...
- 【实战经验】Xilinx时钟从普通IO输出问题
Xilinx芯片的时钟信号从普通IO输出时,在map过程中会出错,对此有两种解决方案: 1.在ucf文件中,添加对应的约束文件: 例如[PIN "U0_1/clkout2_buf.O&quo ...
- nginx通过自定义header属性来转发不同的服务
一.背景 因为需要上线灰度发布,只要nginx接收到头部为: wx_unionid: 就会跳转到另外一个url,比如: 通过配置nginx 匹配请求头wx_unionid 来转发到灰度环境.核心:客户 ...
- MySQl数据库面试题
1. MySQL中索引什么作用? 索引的定义和创建的目的 1) 索引是对数据库表中一列或者多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息 2) 索引的分类:主键索引,唯一索引,常规 ...
- [开发ing] Unity项目 - Hero英雄
目录 游戏原型 项目演示 绘图资源 代码实现 技术探讨 参考来源 游戏原型 游戏介绍:这是一款横版类魂游戏,玩家将操控Hero,在诸神黄昏的墓地中,挑战源源不断的敌人,以及近乎无敌的强大boss 灵感 ...
- .net core webapi通过中间件获取请求和响应内容
本文主要根据中间件来实现对.net core webapi中产生的请求和响应数据进行获取并存入日志文件中: 这里不详细介绍日志文件的使用.你可以自己接入NLog,log4net,Exceptionle ...
- Java 之 Request 对象
一.Request 对象和 Response 对象原理 request和response对象是由服务器创建的,供我们使用的. request对象是来获取请求消息,response对象是来设置响应消息. ...
- django 自定义身份认证
自定义身份认证: Django 自带的认证系统足够应付大多数情况,但你或许不打算使用现成的认证系统.定制自己的项目的权限系统需要了解哪些一些关键点,即Django中哪些部分是能够扩展或替换的.这个文档 ...