BZOJ 2001: [Hnoi2010]City 城市建设
2001: [Hnoi2010]City 城市建设
Time Limit: 20 Sec Memory Limit: 162 MB
Submit: 1132 Solved: 555
[Submit][Status][Discuss]
Description
PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁。Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费。Louis希望建造最少的道路使得国内所有的城市连通。但是由于某些因素,城市之间修建道路需要的花费会随着时间而改变,Louis会不断得到某道路的修建代价改变的消息,他希望每得到一条消息后能立即知道使城市连通的最小花费总和, Louis决定求助于你来完成这个任务。
Input
文件第一行包含三个整数N,M,Q,分别表示城市的数目,可以修建的道路个数,及收到的消息个数。 接下来M行,第i+1行有三个用空格隔开的整数Xi,Yi,Zi(1≤Xi,Yi≤n, 0≤Zi≤50000000),表示在城市Xi与城市Yi之间修建道路的代价为Zi。接下来Q行,每行包含两个数k,d,表示输入的第k个道路的修建代价修改为d(即将Zk修改为d)。
Output
输出包含Q行,第i行输出得知前i条消息后使城市连通的最小花费总和。
Sample Input
1 2 1
2 3 2
3 4 3
4 5 4
5 1 5
1 6
1 1
5 3
Sample Output
10
9
HINT
【数据规模】 对于20%的数据, n≤1000,m≤6000,Q≤6000。 有20%的数据,n≤1000,m≤50000,Q≤8000,修改后的代价不会比之前的代价低。 对于100%的数据, n≤20000,m≤50000,Q≤50000。
Source
十分懵逼的一道CDQ分治。
solve(l,r) 解决l到r区间内的修改及询问。
边界:l==r,可以直接做最小生成树得到答案。
其他:递归之前,需要在当前层进行两个操作:
contraction 求出所有的必须边,并直接把必须边加入答案,之后不再考虑;顺道把必须边连接的两点永久合并。
reduction 求出所有的不可能边,并直接把不可能边删除,之后不再考虑。
把所有待修改的边权值设为-inf,做最小生成树,在MST上的非待修改边都是必须边。
把所有待修改的边权值设为+inf,做最小生成树,不在MST上的非待修改边都是不可能边。
进行两个操作之后,图的规模会缩小,也许是缩小一半,不造,这个太玄学,大爷都不会。
#include <bits/stdc++.h>
inline int getC(void) {
static const int siz = ;
static char buf[siz];
static char *hd = buf + siz;
static char *tl = buf + siz;
if (hd == tl)
fread(hd = buf, , siz, stdin);
return int(*hd++);
}
inline int getI(void) {
register int ret = ;
register int neg = false;
register int bit = getC();
for (; bit < ; bit = getC())
if (bit == '-')neg ^= true;
for (; bit > ; bit = getC())
ret = ret * + bit - '';
return neg ? -ret : ret;
}
typedef long long lnt;
const int inf = 1e9;
const int maxn = ;
const int maxm = ;
int N, M, Q;
int a[maxm];
int c[maxm];
int sum[maxn];
lnt ans[maxm];
struct edge {
int x, y, w, p;
inline friend bool operator <
(const edge &a, const edge &b) {
return a.w < b.w;
}
}e[][maxm], d[maxm], b[maxm];
struct edit {
int x, y;
}q[maxm];
int fa[maxn];
int find(int u) {
return fa[u] == u ? u : fa[u] = find(fa[u]);
}
inline void clear(int t) {
for (int i = ; i <= t; ++i)
fa[d[i].x] = d[i].x,
fa[d[i].y] = d[i].y;
}
inline void merge(int x, int y) {
fa[y] = x;
}
inline void contraction(int &t, lnt &cnt) {
clear(t); int tmp = ;
std::sort(d + , d + + t);
for (int i = ; i <= t; ++i)
if (find(d[i].x) != find(d[i].y))
merge(find(d[i].x), find(d[i].y)), b[++tmp] = d[i];
for (int i = ; i <= tmp; ++i)
fa[b[i].x] = b[i].x,
fa[b[i].y] = b[i].y;
for (int i = ; i <= tmp; ++i)
if (b[i].w != -inf && find(b[i].x) != find(b[i].y))
merge(find(b[i].x), find(b[i].y)), cnt += b[i].w;
tmp = ;
for (int i = ; i <= t; ++i)
if (find(d[i].x) != find(d[i].y)) {
b[++tmp] = d[i];
c[d[i].p] = tmp;
b[tmp].x = find(d[i].x);
b[tmp].y = find(d[i].y);
}
for (int i = ; i <= tmp; ++i)d[i] = b[i];
t = tmp;
}
inline void reduction(int &t) {
clear(t); int tmp = ;
std::sort(d + , d + + t);
for (int i = ; i <= t; ++i)
if (find(d[i].x) != find(d[i].y)) {
merge(find(d[i].x), find(d[i].y));
b[++tmp] = d[i];
c[d[i].p] = tmp;
}
else if (d[i].w == inf) {
b[++tmp] = d[i];
c[d[i].p] = tmp;
}
for (int i = ; i <= tmp; ++i)d[i] = b[i];
t = tmp;
}
void solve(int l, int r, int now, lnt cnt) {
int t = sum[now];
if (l == r)a[q[l].x] = q[l].y;
for (int i = ; i <= t; ++i)
e[now][i].w = a[e[now][i].p];
for (int i = ; i <= t; ++i)
d[i] = e[now][i], c[d[i].p] = i;
if (l == r) {
ans[l] = cnt; clear(t);
std::sort(d + , d + + t);
for (int i = ; i <= t; ++i)
if (find(d[i].x) != find(d[i].y))
merge(find(d[i].x), find(d[i].y)), ans[l] += d[i].w;
return;
}
for (int i = l; i <= r; ++i)
d[c[q[i].x]].w = -inf;
contraction(t, cnt);
for (int i = l; i <= r; ++i)
d[c[q[i].x]].w = inf;
reduction(t);
for (int i = ; i <= t; ++i)
e[now + ][i] = d[i];
sum[now + ] = t;
int mid = (l + r) >> ;
solve(l, mid, now + , cnt);
solve(mid + , r, now + , cnt);
}
signed main(void) {
N = getI();
M = getI();
Q = getI();
for (int i = ; i <= M; ++i) {
e[][i].p = i;
e[][i].x = getI();
e[][i].y = getI();
e[][i].w = getI();
a[i] = e[][i].w;
}
for (int i = ; i <= Q; ++i) {
q[i].x = getI();
q[i].y = getI();
}
sum[] = M;
solve(, Q, , );
for (int i = ; i <= Q; ++i)
printf("%lld\n", ans[i]);
}
@Author: YouSiki
BZOJ 2001: [Hnoi2010]City 城市建设的更多相关文章
- 【刷题】BZOJ 2001 [Hnoi2010]City 城市建设
Description PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少 ...
- 2001: [Hnoi2010]City 城市建设 - BZOJ
DescriptionPS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少的 ...
- BZOJ2001 [Hnoi2010]City 城市建设 CDQ分治
2001: [Hnoi2010]City 城市建设 Time Limit: 20 Sec Memory Limit: 162 MB Description PS国是一个拥有诸多城市的大国,国王Lou ...
- 【BZOJ2001】 [Hnoi2010]City 城市建设
BZOJ2001 [Hnoi2010]City 城市建设 Solution 我们考虑一下这个东西怎么求解? 思考无果...... 咦? 好像可以离线cdq,每一次判断一下如果这条边如果不选就直接删除, ...
- BZOJ2001: [Hnoi2010]City 城市建设
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2001 cdq分治+重建图. 可以保留当前一定会被选的非修改边然后把点缩起来.这样的话每次点数至 ...
- 【bzoj2001】 Hnoi2010—City 城市建设
http://www.lydsy.com/JudgeOnline/problem.php?id=2001 (题目链接) 题意 给出一张无向图,$m$组操作,每次修改一条边的权值,对于每次操作输出修改之 ...
- [HNOI2010]CITY 城市建设
问题: 给一张图,支持边长度修改,求MST 题解: 自己想就想不到了.. 考虑cdq分治 1.首先求出一定有用的边 对于未处理的边,全部设为-INF,求一次MST,出现在MST上的边一定最终出现在后面 ...
- BZOJ2001 [Hnoi2010]City 城市建设 【CDQ分治 + kruskal】
题目链接 BZOJ2001 题解 CDQ分治神题... 难想难写.. 比较朴素的思想是对于每个询问都求一遍\(BST\),这样做显然会爆 考虑一下时间都浪费在了什么地方 我们每次求\(BST\)实际上 ...
- 【HNOI2010】城市建设(对时间分治 & Kruskal)
Description \(n\) 个点 \(m\) 条边的带边权无向图.\(q\) 次操作,每次修改一条边的权值. 求每次修改后的最小生成树的边权和. Hint \(1\le n\le 2\time ...
随机推荐
- sea.js模块化编程
* 为什么要模块化? 解决文件依赖 解决命名冲突 ; var var2 = 2; function fn1(){ } function fn2(){ } return { fn1: fn1, fn2: ...
- transformjs污染了DOM?是你不了解它的强大
原文链接: https://github.com/AlloyTeam/AlloyTouch/wiki/Powerful-transformjs 写在前面 上星期在React微信群里,有小伙伴觉得tra ...
- 使用PowerShell修改操作系统“环境变量”
有时候我们需要命令行工具,但在使用前往往需要先导航至命令工具所在的目录,比如:stsadm 我们首先需要导航至(以SharePoint2013为例):C:\Program Files\Common ...
- Android Weekly Notes Issue #225
Android Weekly Issue #225 October 2nd, 2016 Android Weekly Issue #225 本期内容包括: Android 7.0的Quick Sett ...
- [Erlang 0127] Term sharing in Erlang/OTP 上篇
之前,在 [Erlang 0126] 我们读过的Erlang论文 提到过下面这篇论文: On Preserving Term Sharing in the Erlang Virtual Machine ...
- 使用 python 管理 mysql 开发工具箱 - 1
Mysql 是一个比较优秀的开源的数据库,很多公司都在使用.作为运维人员,经常做着一些重复性的工作,比如创建数据库实例,数据库备份等,完全都可以使用 python 编写一个工具来实现. 一.模块 Co ...
- 如何实现可动态调整隐藏header的listview
(转自:http://blog.sina.com.cn/s/blog_70b9730f01014sgm.html) 需求:根据某种需要,可能需要动态调整listview的页眉页脚,譬如将header作 ...
- plain framework 1 1.0.4 更新 稳定版发布
PF由于各种因素迟迟不能更新,此次更新主要是更新了以往和上个版本出现的内存问题,该版本较为稳定,如果有用到的朋友请更新至此版本. PF 1.0.4 修复1.0.0.3更新后产生的内存问题,可能导致网络 ...
- [No0000AE]在 Visual Studio 中调试 XAML 设计时异常
在 Visual Studio 中进行 WPF, UWP, Silverlight 开发时,经常会遇到 XAML 设计器由于遭遇异常而无法正常显示设计器视图的情况.很多时候由于最终生成的项目在运行时并 ...
- 内网劫持渗透新姿势:MITMf简要指南
声明:本文具有一定攻击性,仅作为技术交流和安全教学之用,不要用在除了搭建环境之外的环境. 0×01 题记 又是一年十月一,想到小伙伴们都纷纷出门旅游,皆有美酒佳人相伴,想到这里,不禁潸然泪下.子曰:& ...