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

5 5 3
1 2 1
2 3 2
3 4 3
4 5 4
5 1 5
1 6
1 1
5 3

Sample Output

14
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

 

[Submit][Status][Discuss]

十分懵逼的一道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 城市建设的更多相关文章

  1. 【刷题】BZOJ 2001 [Hnoi2010]City 城市建设

    Description PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少 ...

  2. 2001: [Hnoi2010]City 城市建设 - BZOJ

    DescriptionPS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少的 ...

  3. BZOJ2001 [Hnoi2010]City 城市建设 CDQ分治

    2001: [Hnoi2010]City 城市建设 Time Limit: 20 Sec  Memory Limit: 162 MB Description PS国是一个拥有诸多城市的大国,国王Lou ...

  4. 【BZOJ2001】 [Hnoi2010]City 城市建设

    BZOJ2001 [Hnoi2010]City 城市建设 Solution 我们考虑一下这个东西怎么求解? 思考无果...... 咦? 好像可以离线cdq,每一次判断一下如果这条边如果不选就直接删除, ...

  5. BZOJ2001: [Hnoi2010]City 城市建设

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2001 cdq分治+重建图. 可以保留当前一定会被选的非修改边然后把点缩起来.这样的话每次点数至 ...

  6. 【bzoj2001】 Hnoi2010—City 城市建设

    http://www.lydsy.com/JudgeOnline/problem.php?id=2001 (题目链接) 题意 给出一张无向图,$m$组操作,每次修改一条边的权值,对于每次操作输出修改之 ...

  7. [HNOI2010]CITY 城市建设

    问题: 给一张图,支持边长度修改,求MST 题解: 自己想就想不到了.. 考虑cdq分治 1.首先求出一定有用的边 对于未处理的边,全部设为-INF,求一次MST,出现在MST上的边一定最终出现在后面 ...

  8. BZOJ2001 [Hnoi2010]City 城市建设 【CDQ分治 + kruskal】

    题目链接 BZOJ2001 题解 CDQ分治神题... 难想难写.. 比较朴素的思想是对于每个询问都求一遍\(BST\),这样做显然会爆 考虑一下时间都浪费在了什么地方 我们每次求\(BST\)实际上 ...

  9. 【HNOI2010】城市建设(对时间分治 & Kruskal)

    Description \(n\) 个点 \(m\) 条边的带边权无向图.\(q\) 次操作,每次修改一条边的权值. 求每次修改后的最小生成树的边权和. Hint \(1\le n\le 2\time ...

随机推荐

  1. 面向对象设计模式纵横谈:Abstract Factory 抽象工厂模式(笔记记录)

         今天是设计模式的第二讲,抽象工厂的设计模式,我们还是延续老办法,一步一步的.演变的来讲,先来看看一个对象创建的问题. 1.如何创建一个对象 常规的对象创建方法: 这样的创建对象没有任何问题, ...

  2. Easyui dialog中嵌入iframe

    如果easyui dialog的地址属性用href超链接,easyui 不会加载整个url页面,只会截取url目标页的body体间的html, 如果想加载把其他页面 加载进dialog的iframe中 ...

  3. 关于MySql的1146错误修正

    在Mysql数据库中建立连接Mysql后建立了一个数据库名叫Mysql后删除了系统自动建立的数个表,导入.sql文件运行后,想要运行相关的SQL语句却发现一些未知错误为 Table 'mysql.pr ...

  4. iosselect:一个js picker项目,在H5中实现IOS的下拉效果

    iosselect是在webapp下的一个picker组件,可以轻松实现各类选择器效果.比如地区选择 时间选择 日期选择等. 下面是一个地址选择器demo截图,可以访问:http://zhoushen ...

  5. AlloyRenderingEngine文本框组件

    写在前面 Github: https://github.com/AlloyTeam/AlloyGameEngine 在dom元素里,自带了input标签,设置其type为text,它就是一个文本框. ...

  6. android Intent介绍

    Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作.动作涉及数据.附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 ...

  7. [Modern OpenGL系列(四)]在OpenGL中使用Shader

    本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51347440 在上一篇文章中已经介绍了OpenGL窗口的创建.本文接着说如 ...

  8. Play Framework 完整实现一个APP(十三)

    添加用户编辑区 1.修改Admin.index() public static void index() { List<Post> posts = Post.find("auth ...

  9. T-SQL 将动态SQL的结果集赋值到变量

    1. 使用输出变量 ) ) DECLARE @counts int SET @city = 'New York' SET @sqlCommand = 'SELECT @cnt=COUNT(*) FRO ...

  10. sql面试题(学生表_课程表_成绩表_教师表)

    原帖链接:http://bbs.csdn.net/topics/280002741 表架构 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程 ...