题目

PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁。Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费。Louis希望建造最少的道路使得国内所有的城市连通。但是由于某些因素,城市之间修建道路需要的花费会随着时间而改变,Louis会不断得到某道路的修建代价改变的消息,他希望每得到一条消息后能立即知道使城市连通的最小花费总和, Louis决定求助于你来完成这个任务。

题解

经典的动态最小生成树问题。

可以采用cdq分治的方式来解决。

核心思想就是:

  1. 对于无论被修改的边修改成什么样都一定会被加入的非修改边进行缩点以减小数据范围。
  2. 对于无论被修改的边修改成什么样都一定不被加入的非修改边进行删除以减小数据范围。

对于两种边的确定可以直接设被修改的边的边权为-inf或inf,然后跑Kruskal确定

复杂度。。。

他们说是\(O(nlog^2n)\)的。。。

反正跑的很快就是了。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;static char ch;static bool flag;flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 50010;
const int maxm = 100010;
const int inf = 0x3f3f3f3f;
struct Edge{
int u,v,w,id;
bool friend operator < (const Edge &a,const Edge &b){
return a.w < b.w;
}
}e[30][maxm],L[maxm],tmp[maxm];
int Nn[30],Ne[30];
int fa[maxn];
inline int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
inline bool merge(int u,int v){
int x = find(u);
int y = find(v);
if(x == y) return false;
fa[x] = y;return true;
}
int val[maxm];
struct Node{
int k,w;
}qer[maxm];
bool vis[maxm];
int tmp_n[maxn],tmp_m[maxm],map[maxm];
ll ans[maxm];
inline void step1(int &n,int &m,ll &res){
int N = 0,M = 0;
rep(i,1,n) fa[i] = i;
rep(i,0,m-1) vis[i] = 0;
sort(L,L+m);
rep(i,0,m-1){
if(merge(L[i].u,L[i].v) && L[i].w != -inf){
res += L[i].w;
vis[i] = true;
}else tmp[M ++ ] = L[i];
}
rep(i,1,n) fa[i] = i;
rep(i,0,m-1) if(vis[i]) merge(L[i].u,L[i].v);
rep(i,1,n) if(find(i) == i) tmp_n[i] = ++ N;
rep(i,1,n) tmp_n[i] = tmp_n[find(i)];
rep(i,0,M-1){
L[i] = tmp[i];
map[L[i].id] = i;
L[i].u = tmp_n[L[i].u];
L[i].v = tmp_n[L[i].v];
}
n = N;m = M;
}
inline void step2(int &n,int &m){
int M = 0;
rep(i,1,n) fa[i] = i;
sort(L,L+m);
rep(i,0,m-1){
if(merge(L[i].u,L[i].v) || L[i].w == inf){
map[L[i].id] = M;
L[M++] = L[i];
}
}m = M;
}
inline void solve(int l,int r,int cur,ll res){
int n = Nn[cur],m = Ne[cur];
if(l == r) val[qer[r].k] = qer[r].w;
rep(i,0,m-1){
e[cur][i].w = val[e[cur][i].id];
L[i] = e[cur][i];
map[L[i].id] = i;
}
if(l == r){
rep(i,1,n) fa[i] = i;
sort(L,L+m);
rep(i,0,m-1){
if(merge(L[i].u,L[i].v)) res += L[i].w;
}
ans[l] = res;
return ;
}
rep(i,l,r) L[map[qer[i].k]].w = -inf;step1(n,m,res);
rep(i,l,r) L[map[qer[i].k]].w = inf;step2(n,m);
Nn[cur+1] = n;Ne[cur+1] = m;
rep(i,0,m-1) e[cur+1][i] = L[i];
int mid = l+r >> 1;
solve(l,mid,cur+1,res);
solve(mid+1,r,cur+1,res);
}
int main(){
int n,m,Q;read(n);read(m);read(Q);
rep(i,0,m-1){
read(e[0][i].u);
read(e[0][i].v);
read(e[0][i].w);
val[i] = e[0][i].w;
e[0][i].id = i;
}
rep(i,1,Q){
read(qer[i].k);read(qer[i].w);
-- qer[i].k;
}
Nn[0] = n;Ne[0] = m;
solve(1,Q,0,0);
rep(i,1,Q) printf("%lld\n",ans[i]);
return 0;
}

bzoj 2001: City 城市建设 cdq的更多相关文章

  1. bzoj 2001 CITY 城市建设 cdq分治

    题目传送门 题解: 对整个修改的区间进行分治.对于当前修改区间来说,我们对整幅图中将要修改的边权都先改成-inf,跑一遍最小生成树,然后对于一条树边并且他的权值不为-inf,那么这条边一定就是树边了. ...

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

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

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

    2001: [Hnoi2010]City 城市建设 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1132  Solved: 555[Submit][ ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. phpcms的基础知识和配置

    一.设置界面 1.站点设置:相当于服务器上的站点 (1)站点修改:“关键词”和“描述”的修改,便于网络优化和搜索引擎对本网站的搜索. (2)点击站点后边的修改,模板的修改,引用自己模板 2.基本设置: ...

  2. 【BZOJ3651】网络通信 LCT

    [BZOJ3651]网络通信 Description 有一个由M 条电缆连接的 N 个站点组成的网络.为了防止垄断,由 C 个公司控制所有的电缆,规定任何公司不能控制连接同一个站点的两条以上的电缆(可 ...

  3. 【BZOJ5018】[Snoi2017]英雄联盟 背包

    [BZOJ5018][Snoi2017]英雄联盟 Description 正在上大学的小皮球热爱英雄联盟这款游戏,而且打的很菜,被网友们戏称为「小学生」.现在,小皮球终于受不了网友们的嘲讽,决定变强了 ...

  4. eclipse里面用svn关联项目

    eclipse里面共享项目经常会用到svn或者git插件 关联项目的步骤如下: 如果 点击finish会遇到卡住问题的话,不要着急,我们需要设置svn的client设置: 如果设置了之后还是很卡的话, ...

  5. 红米4A手机刷开发版rom并且获取root权限

    1 bl解锁 Critical partition flashing is not allowed就是因为没有bl解锁. 注册小米账号并且关联手机. 下载bl解锁工具 http://www.miui. ...

  6. mybatis generator的用法

    1 自动生成代码 配置数据库 自动生成三个文件: 第一,java bean文件: 第二,java bean对应的dao文件,但是这里的dao只是一个接口: 第三,mybatis需要的Mapper文件: ...

  7. [Android]彻底去除Google AdMob广告

    应用中包含广告是能够理解的,但经常造成用户误点,或者广告切换时造成下载流量,就有点让人不舒服了. 以下就以Google AdMob广告为例,看怎样彻底去除他. 先分析一下Google AdMob的工作 ...

  8. Mac下nginx安装和配置

    nginx安装 brew search nginx brew install nginx 安装完以后,可以在终端输出的信息里看到一些配置路径: /usr/local/etc/nginx/nginx.c ...

  9. unix网络编程笔记(二)

    第四章笔记 1. 基本Tcpclient/server程序的套接字函数 2. socket函数: int socket(int family,int type,int protocol); (1)so ...

  10. 模仿jquery框架源码---网络

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Untitled Page& ...