2001: [Hnoi2010]City 城市建设

Time Limit: 20 Sec  Memory Limit: 162 MB

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。

(转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/8028462.html )

想法题……太神了
最暴力的当然是$O(n^{2}logn)$的暴力,但是这样操作的次数就太多了,我们需要优化
或者优化每次的边数,或者优化操作的次数
优化操作次数显然是不行的……
我们会发现,有一些“绝对不可能成为最优解”的边在暴力里被重复排序了
那么我们可以直接把他们删掉,来减少这种影响。
另外,有一些“绝对存在于最优解中“的边,我们预先计入他们的值,并在边集中去除它们并缩点
这样我们就有了分治的思路,对”每个修改操作控制的时间“分治

代码打起来倒不是很长……
两份代码是两种实现方法,第一份来自FoolMike神犇……是上面说的按时间分治,比较优秀
只有存在时间完全覆盖了l~r这个时间段的边才存在,
并且有缩点和删边2个优化操作。
至于第二份……是自己打的,每次把这段时间内被修改的边标记成+inf和-inf,+inf时没被选上的边是要删去的,
-inf时被选上的边是要必须选的。优化没有打好,也就比暴力强一点……
这份代码是给自己存着解闷的,想研究程序的请看第一份23333

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define inf 50000001
#define N 20010
#define M 50010
#define LL long long
char B[<<],*cS=B,*cT=B;
#define getc (cS==cT&&(cT=(cS=B)+fread(B,1,1<<15,stdin),cS==cT)?0:*cS++)
inline int read()
{
int x=;register char c=getc;
while(c<''||c>'')c=getc;
while(c>=''&&c<='')x=*x+(c^),c=getc;
return x;
}
int n,m,q;
struct edge{int st,ed,val,L,R;}s[M];
vector<edge>E;
struct Gragh
{
int fa[N];
inline int find(int a){return fa[a]==a?a:fa[a]=find(fa[a]);}
inline void intn(int sz){for(int i=;i<=sz;++i)fa[i]=i;}
}S;
inline bool mt(const edge &a,const edge &b){return a.val<b.val;}
LL ans[M];
int sta[M<<],stb[M<<],stc[M<<];
int id[N];
inline void CDQ(int l,int r,int size,vector<edge> Ex)
{
vector<edge> tmp;
int i,sz,x,y,cnt,mi=l+r>>;edge z;
for(i=,sz=Ex.size();i<sz;++i)
if(l<=Ex[i].R&&Ex[i].L<=r)tmp.push_back(Ex[i]);
sort(tmp.begin(),tmp.end(),mt);
S.intn(size);LL temp=;
for(i=,sz=tmp.size();i<sz;++i)
{
z=tmp[i],stc[i]=(z.L<=l&&r<=z.R),
sta[i]=stb[i]=,x=S.find(z.st),y=S.find(z.ed);
if(x!=y)
{
S.fa[x]=y;
if(stc[i])temp+=z.val,sta[i]=;
}
}
for(i=l;i<=r;++i)ans[i]+=temp;
if(l==r)return;
S.intn(size);
for(i=,sz=tmp.size();i<sz;++i)
{
z=tmp[i],x=S.find(z.st),y=S.find(z.ed);
if(x==y)stb[i]=;
else if(stc[i])S.fa[x]=y;
}
S.intn(size);
for(i=,sz=tmp.size();i<sz;++i)
if(sta[i]){z=tmp[i],S.fa[S.find(z.st)]=S.find(z.ed);}
for(cnt=,i=;i<=size;++i)
if(S.find(i)==i)id[i]=++cnt;
Ex.clear();
for(i=,sz=tmp.size();i<sz;++i)
if(!sta[i]&&!stb[i])
tmp[i].st=id[S.find(tmp[i].st)],
tmp[i].ed=id[S.find(tmp[i].ed)],
Ex.push_back(tmp[i]);
CDQ(l,mi,cnt,Ex);
CDQ(mi+,r,cnt,Ex);
}
int last[M];
int main()
{
register int i,j,x,y;edge z;
n=read(),m=read(),q=read();
for(i=;i<=m;++i)
s[i].st=read(),s[i].ed=read(),s[i].val=read();
for(i=;i<=q;++i)
x=read(),y=read(),z=s[x],z.L=last[x],z.R=i-,
E.push_back(z),s[x].val=y,last[x]=i;
for(i=;i<=m;++i)
s[i].L=last[i],s[i].R=q,E.push_back(s[i]);
CDQ(,q,n,E);
for(i=;i<=q;++i)
printf("%lld\n",ans[i]);
}

能AC的程序

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define inf 50000001
#define N 20010
#define M 50010
#define LL long long
char B[<<],*S=B,*T=B;
#define getc (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)
inline int read()
{
int x=;register char c=getc;
while(c<''||c>'')c=getc;
while(c>=''&&c<='')x=*x+(c^),c=getc;
return x;
}
int n,m,q,top,sta[M],stb[M],topa;
int st[M],ed[M],val[M];
int changeid[M],changeval[M],mem[M];
inline bool mt(const int &a,const int &b){return val[a]<val[b];}
struct Gragh
{
int fa[N];int already;
vector<int>edge;
inline void operator = (const Gragh &b)
{memcpy(fa,b.fa,sizeof(fa)),edge=b.edge,already=b.already;}
inline int find(int a)
{return fa[a]==a?a:fa[a]=find(fa[a]);}
}G[];
LL ans[M];
inline void CDQ(int l,int r,int layer)
{
vector<int>::iterator it;
int i,sz,x,y,mi=l+r>>;
if(l==r)
{
val[changeid[l]]=changeval[l];
sort(G[layer].edge.begin(),G[layer].edge.end(),mt);
for(it=G[layer].edge.begin();G[layer].already<n-&&it!=G[layer].edge.end();++it)
{
x=G[layer].find(st[*it]),y=G[layer].find(ed[*it]);
if(x!=y)++G[layer].already,G[layer].fa[x]=y,ans[l]+=val[*it];
}
return;
}
for(int i=l;i<=r;++i)mem[changeid[i]]=val[changeid[i]];
for(int i=l;i<=r;++i)val[changeid[i]]=-inf;
sort(G[layer].edge.begin(),G[layer].edge.end(),mt);
LL temp=;sz=;topa=;
for(it=G[layer].edge.begin();sz!=n-&&G[layer].already!=n-&&it!=G[layer].edge.end();++it)
{
x=G[layer].find(st[*it]),y=G[layer].find(ed[*it]);
if(x!=y)
{
++sz,G[layer].fa[x]=y;
if(val[*it]!=-inf)sta[++topa]=*it,temp+=val[*it],++G[layer].already;
}
}
for(x=l;x<=r;++x)ans[x]+=temp;
G[layer]=G[layer-];
for(int i=l;i<=r;++i)val[changeid[i]]=inf;
sort(G[layer].edge.begin(),G[layer].edge.end(),mt);
memset(stb,,sizeof(stb));
for(sz=,it=G[layer].edge.begin();sz!=n-&&it!=G[layer].edge.end();++it)
{
x=G[layer].find(st[*it]),y=G[layer].find(ed[*it]);
if(x!=y)++sz,G[layer].fa[x]=y;
else if(val[*it]!=inf)stb[*it]=;
}
for(;it!=G[layer].edge.end();++it)
if(val[*it]!=inf)stb[*it]=;
G[layer]=G[layer-];
for(i=;i<=topa;++i)
x=G[layer].find(st[sta[i]]),y=G[layer].find(ed[sta[i]]),G[layer].fa[x]=y;
for(i=,sz=G[layer].edge.size();i<sz;++i)
if(stb[ G[layer].edge[i] ])
G[layer].edge[i]=G[layer].edge[sz-],--sz,--i,G[layer].edge.pop_back();
for(int i=l;i<=r;++i)val[changeid[i]]=mem[changeid[i]];
G[layer+]=G[layer],CDQ(l,mi,layer+);
G[layer+]=G[layer],CDQ(mi+,r,layer+);
}
int main()
{
register int i,j;n=read(),m=read(),q=read();
for(i=;i<=m;++i)
st[i]=read(),ed[i]=read(),val[i]=read(),
G[].edge.push_back(i),G[].edge.push_back(i);
for(i=;i<=n;++i)G[].fa[i]=G[].fa[i]=i;
G[].already=G[].already=;
for(i=;i<=q;++i)
changeid[i]=read(),changeval[i]=read();
CDQ(,q,);
for(i=;i<=q;++i)
printf("%lld\n",ans[i]);
}

TLE的程序

BZOJ2001 [Hnoi2010]City 城市建设 CDQ分治的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. bzoj 2001: City 城市建设 cdq

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

  8. [HNOI2010]CITY 城市建设

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

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

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

随机推荐

  1. POJ 3687 Labeling Balls(反向拓扑+贪心思想!!!非常棒的一道题)

    Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16100   Accepted: 4726 D ...

  2. js中数组的使用

    使用js时候,很多情况下要使用数组.就写写数组中一些常用的方法. js中定义一个数组,一般有以下2种方法. 1. var arr = new Array(3); // 声明数组有3个元素 arr[0] ...

  3. linux下使用软连接之案例二

           在笔者的上一篇文章介绍过怎么通过linux的软连接在不修改上传代码的情况下,将上传到项目路径下的图片改为上传到项目外面,防止重新部署后图片被删除了.同时还可以直接通过类似访问静态资源的方 ...

  4. mfc CFileFind查找类

    查找文件 CFileFind类 提取文件图标 显示大图标 显示小图标 一.查找文件 . CFileFind类 //c:\mydir\myfile.txt GetFileName 获取文件名 myfil ...

  5. Elasticsearch Query DSL 整理总结(一)—— Query DSL 概要,MatchAllQuery,全文查询简述

    目录 引言 概要 Query and filter context Match All Query 全文查询 Full text queries 小结 参考文档 引言 虽然之前做过 elasticse ...

  6. R语言学习 第四篇:函数和流程控制

    变量用于临时存储数据,而函数用于操作数据,实现代码的重复使用.在R中,函数只是另一种数据类型的变量,可以被分配,操作,甚至把函数作为参数传递给其他函数.分支控制和循环控制,和通用编程语言的风格很相似, ...

  7. 设计模式 笔记 策略模式 Strategy

    //---------------------------15/04/28---------------------------- //Strategy 策略模式----对象行为型模式 /* 1:意图 ...

  8. 解决Docker容器时区及时间不同步的问题

    前几天在测试应用的功能时,发现存入数据库中的数据create_time或者update_time字段总是错误,其他数据都是正常的,只有关于时间的字段是错误的. 进入linux服务器中查看,也没有任何的 ...

  9. SpringBoot日记——Redis整合

    上一篇文章,简单记录了一下缓存的使用方法,这篇文章将把我们熟悉的redis整合进来. 那么如何去整合呢?首先需要下载和安装,为了使用方便,也可以做环境变量的配置. 下载和安装的方法,之前有介绍,在do ...

  10. Istio全景监控与拓扑

    根据Istio官方报告,Observe(可观察性)为其重要特性.Istio提供非侵入式的自动监控,记录应用内所有的服务. 我们知道在Istio的架构中,Mixer是管理和收集遥测信息的组件.每一次当请 ...