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 ...
随机推荐
- 面向对象设计模式纵横谈:Abstract Factory 抽象工厂模式(笔记记录)
今天是设计模式的第二讲,抽象工厂的设计模式,我们还是延续老办法,一步一步的.演变的来讲,先来看看一个对象创建的问题. 1.如何创建一个对象 常规的对象创建方法: 这样的创建对象没有任何问题, ...
- Easyui dialog中嵌入iframe
如果easyui dialog的地址属性用href超链接,easyui 不会加载整个url页面,只会截取url目标页的body体间的html, 如果想加载把其他页面 加载进dialog的iframe中 ...
- 关于MySql的1146错误修正
在Mysql数据库中建立连接Mysql后建立了一个数据库名叫Mysql后删除了系统自动建立的数个表,导入.sql文件运行后,想要运行相关的SQL语句却发现一些未知错误为 Table 'mysql.pr ...
- iosselect:一个js picker项目,在H5中实现IOS的下拉效果
iosselect是在webapp下的一个picker组件,可以轻松实现各类选择器效果.比如地区选择 时间选择 日期选择等. 下面是一个地址选择器demo截图,可以访问:http://zhoushen ...
- AlloyRenderingEngine文本框组件
写在前面 Github: https://github.com/AlloyTeam/AlloyGameEngine 在dom元素里,自带了input标签,设置其type为text,它就是一个文本框. ...
- android Intent介绍
Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作.动作涉及数据.附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 ...
- [Modern OpenGL系列(四)]在OpenGL中使用Shader
本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51347440 在上一篇文章中已经介绍了OpenGL窗口的创建.本文接着说如 ...
- Play Framework 完整实现一个APP(十三)
添加用户编辑区 1.修改Admin.index() public static void index() { List<Post> posts = Post.find("auth ...
- T-SQL 将动态SQL的结果集赋值到变量
1. 使用输出变量 ) ) DECLARE @counts int SET @city = 'New York' SET @sqlCommand = 'SELECT @cnt=COUNT(*) FRO ...
- sql面试题(学生表_课程表_成绩表_教师表)
原帖链接:http://bbs.csdn.net/topics/280002741 表架构 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程 ...