博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ2001】 [Hnoi2010]City 城市建设
阅读量:6816 次
发布时间:2019-06-26

本文共 2234 字,大约阅读时间需要 7 分钟。

BZOJ2001 [Hnoi2010]City 城市建设


Solution

我们考虑一下这个东西怎么求解?

思考无果......

咦?

好像可以离线cdq,每一次判断一下如果这条边如果不选就直接删除,然后不确定的保留,必须选的就去确定连通性.

然后可以了?

好妙啊.cdq果然还是万金油.

代码实现

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define re register#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)inline int gi(){ int f=1,sum=0;char ch=getchar(); while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();} return f*sum;}const int N=100010,Inf=1e9+10;struct node{ int u,v,w,id; bool operator<(const node b)const{ return w
-Inf){ f[find(st[i].u)]=find(st[i].v); Ans+=st[i].w; } top=0; for(int i=1;i<=z;i++) if(find(tmp[i].u)!=find(tmp[i].v)){ st[++top]=tmp[i]; c[tmp[i].id]=top; st[top].u=find(tmp[i].u); st[top].v=find(tmp[i].v); } z=top;for(int i=1;i<=top;i++)tmp[i]=st[i];}void Solve2(int &z){ init(z);sort(&tmp[1],&tmp[z+1]);int top=0; for(int i=1;i<=z;++i) if(find(tmp[i].u)!=find(tmp[i].v)) f[find(tmp[i].u)]=find(tmp[i].v),st[++top]=tmp[i],c[tmp[i].id]=top; else if(tmp[i].w>=Inf)st[++top]=tmp[i],c[tmp[i].id]=top; z=top;for(int i=1;i<=top;++i)tmp[i]=st[i];}void cdq(int l,int r,int dep,ll Ans){ if(l==r)W[q[l].x]=q[l].w; int z=siz[dep],mid=(l+r)>>1; for(int i=1;i<=z;i++)e[dep][i].w=W[e[dep][i].id]; for(int i=1;i<=z;i++)tmp[i]=e[dep][i],c[tmp[i].id]=i; if(l==r){ init(z);sort(tmp+1,tmp+z+1); for(int i=1;i<=z;i++) if(find(tmp[i].u)!=find(tmp[i].v)){ f[find(tmp[i].u)]=find(tmp[i].v);Ans+=tmp[i].w; } ans[l]=Ans;return; } for(int i=l;i<=r;i++)tmp[c[q[i].x]].w=-Inf; Solve1(z,Ans); for(int i=l;i<=r;i++)tmp[c[q[i].x]].w=+Inf; Solve2(z); for(int i=1;i<=z;i++)e[dep+1][i]=tmp[i];siz[dep+1]=z; cdq(l,mid,dep+1,Ans);cdq(mid+1,r,dep+1,Ans);}int main(){ int n,m,Q; n=gi();m=gi();Q=gi(); for(int i=1;i<=m;i++)E[i].u=gi(),E[i].v=gi(),E[i].w=gi(),E[i].id=i; for(int i=1;i<=Q;i++)q[i].x=gi(),q[i].w=gi(); for(int i=1;i<=m;i++)W[i]=E[i].w; for(int i=1;i<=m;i++)e[0][i]=E[i]; siz[0]=m;cdq(1,Q,0,0); for(int i=1;i<=Q;i++)printf("%lld\n",ans[i]); return 0;}

转载于:https://www.cnblogs.com/mle-world/p/10320729.html

你可能感兴趣的文章
angerfire宋杨的桌面秀
查看>>
用JQuery给图片添加鼠标移入移出事件
查看>>
ALTER TABLE & ALTER TYPES
查看>>
Hadoop-调优剖析
查看>>
Mac前端抓包小工具Charles4.0下载
查看>>
用AHP层次分析法挑选最佳结婚对象
查看>>
Subversion安装手记
查看>>
Effective C++ 阅读笔记(二)public继承与继承中的函数覆盖
查看>>
Centos 学习大纲
查看>>
常见的JavaScript易错知识点整理
查看>>
李开复:钉钉是大胆的突破式创新
查看>>
夏普欲收回美洲品牌授权 海信总裁:严格按照合同办
查看>>
大数据市场迎来扩容期 本土内存数据库抢位崛起
查看>>
IPython4_Notebook
查看>>
rac问题思考总结
查看>>
Android 自定义View总结
查看>>
.NET平台开源项目速览(5)深入使用与扩展SharpConfig组件
查看>>
u-boot-1.3.4 移植到S3C2440
查看>>
HotSpot运行时概览#2
查看>>
Go结构体标签表达式v1.0发布,参数校验杀手锏
查看>>