BZOJ_2238_Mst_树剖+线段树
BZOJ_2238_Mst_树剖+线段树
Description
Input
Output
Sample Input
1 2 3
1 3 5
2 3 9
2 4 1
4
1
2
3
4
Sample Output
15
13
9
Not connected
我们先求任意一棵最小生成树。
如果被删除的边(x->y)不在树上,则直接输出最小生成树的边权和即可。
否则我们要找到所有能使x,y两点连通的边中边权最小的那个,把它换上。
在插入每条非树边时用这条边的权值更新树上x->y路径上权值的最小值,同时记录边权最小的边的编号。
然后这个可以用树剖+线段树维护出来。
注意如果图不联通要输出Not connected,
代码:
- #include <stdio.h>
- #include <string.h>
- #include <algorithm>
- using namespace std;
- #define ls p<<1
- #define rs p<<1|1
- #define N 100050
- int head[N],to[N<<1],nxt[N<<1],cnt,n,m;
- int mn[N<<2],f[N],sum,ref[N],val[N<<1];
- int dep[N],fa[N],top[N],siz[N],son[N],idx[N],tot;
- struct A {
- int x,y,z,flg,id;
- }a[N];
- bool cmp1(const A &x,const A &y) {return x.z<y.z;}
- bool cmp2(const A &x,const A &y) {return x.id<y.id;}
- int find(int x) {
- return f[x]==x?x:f[x]=find(f[x]);
- }
- inline void add(int u,int v,int w) {
- to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
- }
- void dfs1(int x,int y) {
- int i;
- dep[x]=dep[y]+1; fa[x]=y; siz[x]=1;
- for(i=head[x];i;i=nxt[i]) {
- if(to[i]!=y) {
- ref[val[i]]=to[i];
- dfs1(to[i],x); siz[x]+=siz[to[i]];
- if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
- }
- }
- }
- void dfs2(int x,int t) {
- top[x]=t;idx[x]=++tot;
- if(son[x]) dfs2(son[x],t);
- int i;
- for(i=head[x];i;i=nxt[i]) {
- if(to[i]!=fa[x]&&to[i]!=son[x]) {
- dfs2(to[i],to[i]);
- }
- }
- }
- void update(int l,int r,int x,int y,int v,int p) {
- if(x<=l&&y>=r) {
- mn[p]=min(mn[p],v); return ;
- }
- int mid=(l+r)>>1;
- if(x<=mid) update(l,mid,x,y,v,ls);
- if(y>mid) update(mid+1,r,x,y,v,rs);
- }
- int query(int l,int r,int x,int p) {
- if(l==r) return mn[p];
- int mid=(l+r)>>1;
- if(x<=mid) return min(mn[p],query(l,mid,x,ls));
- else return min(mn[p],query(mid+1,r,x,rs));
- }
- int main() {
- scanf("%d%d",&n,&m);
- int i,ne=0,x,y;
- for(i=1;i<=n;i++) f[i]=i;
- for(i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z),a[i].id=i;
- sort(a+1,a+m+1,cmp1);
- for(i=1;i<=m;i++) {
- int dx=find(a[i].x),dy=find(a[i].y);
- if(dx!=dy) {
- add(a[i].x,a[i].y,a[i].id);
- add(a[i].y,a[i].x,a[i].id);
- ne++;
- f[dx]=dy;
- a[i].flg=1;
- sum+=a[i].z;
- if(ne==n-1) break;
- }
- }
- int q;
- if(ne<n-1) {
- scanf("%d",&q);
- while(q--) {
- puts("Not connected");
- }
- return 0;
- }
- dfs1(1,0); dfs2(1,1);
- for(i=1;i<=4*n;i++) mn[i]=1<<30;
- sort(a+1,a+m+1,cmp2);
- for(i=1;i<=m;i++) {
- if(!a[i].flg) {
- x=a[i].x,y=a[i].y;
- while(top[x]!=top[y]) {
- if(dep[top[x]]>dep[top[y]]) swap(x,y);
- update(1,n,idx[top[y]],idx[y],a[i].z,1);
- y=fa[top[y]];
- }
- if(dep[x]<dep[y]) swap(x,y);
- if(x!=y)update(1,n,idx[y]+1,idx[x],a[i].z,1);
- }
- }
- int k;
- scanf("%d",&q);
- while(q--) {
- scanf("%d",&k);
- if(!a[k].flg) {
- printf("%d\n",sum);
- }else {
- x=a[k].x;y=a[k].y;
- int re=query(1,n,idx[ref[k]],1);
- if(re==(1<<30)) {
- puts("Not connected");
- }else {
- printf("%d\n",sum-a[k].z+re);
- }
- }
- }
- }
BZOJ_2238_Mst_树剖+线段树的更多相关文章
- BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树
BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...
- BZOJ_2157_旅游_树剖+线段树
BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...
- 【BZOJ5210】最大连通子块和 树剖线段树+动态DP
[BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...
- [LNOI2014]LCA(树剖+线段树)
\(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...
- [CF1007D]Ants[2-SAT+树剖+线段树优化建图]
题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...
- LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)
题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...
- BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)
传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...
- 【bzoj4699】树上的最短路(树剖+线段树优化建图)
题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...
- POJ3237 Tree(树剖+线段树+lazy标记)
You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbe ...
随机推荐
- Centos 7 卸载自带的openjdk
[root@localhost ~]# rpm -qa|grep jdk java-1.6.0-openjdk-1.6.0.0-1.50.1.11.5.el6_3.x86_64 java-1.7.0- ...
- [ SSH框架 ] Hibernate框架学习之四(JPA)
一.JPA概述以及它和Hibernate之间的关系 1.1.Hibernate 概述 JPA Java Persistence API,是EJB3规范中负责对象持久化的应用程序编程接口(ORM接口), ...
- ERR_NAME_NOT_RESOLVED错误的解决
参考:http://zhidao.baidu.com/link?url=-Beq80OXoSKef_9SmGXkQHvq2AkSE0aGfac02ykorglQF6JTP7F1XNtVxFn9EMfn ...
- MySQL 的索引优化
索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的IO成本.MySQL在300万条记录左右性能开始逐渐下降,虽然官方文档说500~800w记录,所以大数据量建立索引是非常有必要的.My ...
- ThinkPHP5从零基础搭建CMS系统(二)
接上节,开启wamp集成环境,在浏览器地址栏输入http://localhost/cms/public,即可运行项目,但是这边域名太长,做一下处理. 注:需要查看tp5全部教程,请点击右侧thinkp ...
- NewLife.Net——管道处理器解决粘包
Tcp网络编程,必须要解决的一个问题就是粘包,尽管解决办法有很多,这里讲一个比较简单的方法. 老规矩,先上代码:https://github.com/nnhy/NewLife.Net.Tests 一. ...
- Python 3 利用 Dlib 19.7 实现摄像头人脸识别
0.引言 利用python开发,借助Dlib库捕获摄像头中的人脸,提取人脸特征,通过计算欧氏距离来和预存的人脸特征进行对比,达到人脸识别的目的: 可以自动从摄像头中抠取人脸图片存储到本地: 根据抠取的 ...
- HTML学习笔记7:图片与超链接
①图片 <img/>标签,属性有: src,图片链接,分绝对路径和相对路径 width宽度 height,高度 ②超链接 <a> 内容描述 ...
- SSH密钥认证添加方法和一些实用配置
更改SSH端口号 用账号密码进入主机 sudo nano /etc/ssh/sshd-config 再其中添加Port 22等或改变该条 添加公钥到主机 cd ~ sudo mkdir .ssh 此处 ...
- 【python3】如何建立爬虫代理ip池
一.为什么需要建立爬虫代理ip池 在众多的网站防爬措施中,有一种是根据ip的访问频率进行限制的,在某段时间内,当某个ip的访问量达到一定的阀值时,该ip会被拉黑.在一段时间内被禁止访问. 这种时候,可 ...