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. 运算符.png

  2. 2016年6月份那些最实用的 jQuery 插件专辑

    jQuery 是一个快速.流行的 JavaScript 库,jQuery 用于文档处理.事件处理.动画和 Ajax 交互非常简单,学习曲线也很平坦.2016年6月的 jQuery 插件专辑里,我们选择 ...

  3. 移动端web开发——视口

    本篇主要是记录一下移动端视口的分类说明和其它的一些知识.在开始之前,先看一个典型的例子: <meta name="viewport" content="width= ...

  4. CentOS7中安装Python3.5

    1.下载 https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz 2.上传到服务器 3. 安装相关依赖 yum install gcc ope ...

  5. Xamarin Android Activity全屏的两种方式

    方式一 直接在Activity的Attribute中定义 如下 在 MainActivity 中 [Activity(Label = "app", MainLauncher = t ...

  6. visual studio自动导入 using 的快捷键

    快捷键是  shift + alt + f10 ,从 vs 2012开始 还增加了 ctrl+.  功能名称叫: 视图.显示智能标记

  7. MTU(Maximum transmission unit) 最大传输单元

    最大传输单元(Maximum transmission unit),以太网MTU为1500. 不同网络MTU如下: 如果最大报文数据大小(MSS)超过MTU,则会引起分片操作.   路径MTU: 网路 ...

  8. Linux下用ftp更新web内容!

    使用ftp更新web!让网页更新一次OK! 配置如下: 1.在Linux下安装ftp服务器! yum -y install vsftpd #ftp由vsftpd提供! 2.配置主配置文件/etc/vs ...

  9. 不透明度opacity进阶

    一.opacity属性 1.opacity 习惯上说“透明度”,其实应该叫“不透明度”.opacity 意思:不透明,而背景色的默认值:transparent意思才是“透明的”.所以opacity用来 ...

  10. AJAX提交方法(POST)Demon

    AJAX的POST提交方法,本质上来看和GET差不多,有些细小的区别,POST要提交数据时,需要setRequestHeader()方法来提交HTTP头,然后send()方法中提交数据(格式为:&qu ...