BZOJ_2238_Mst_树剖+线段树

Description

给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树。(各询问间独立,每次询问不对之后的询问产生影响,即被删掉的边在下一条询问中依然存在)

Input

第一行两个正整数N,M(N<=50000,M<=100000)表示原图的顶点数和边数。
下面M行,每行三个整数X,Y,W描述了图的一条边(X,Y),其边权为W(W<=10000)。保证两点之间至多只有一条边。
接着一行一个正整数Q,表示询问数。(1<=Q<=100000)
下面Q行,每行一个询问,询问中包含一个正整数T,表示把编号为T的边删掉(边从1到M按输入顺序编号)。

Output

Q行,对于每个询问输出对应最小生成树的边权和的值,如果图不连通则输出“Not connected”

Sample Input

4 4
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,

代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. using namespace std;
  5. #define ls p<<1
  6. #define rs p<<1|1
  7. #define N 100050
  8. int head[N],to[N<<1],nxt[N<<1],cnt,n,m;
  9. int mn[N<<2],f[N],sum,ref[N],val[N<<1];
  10. int dep[N],fa[N],top[N],siz[N],son[N],idx[N],tot;
  11. struct A {
  12. int x,y,z,flg,id;
  13. }a[N];
  14. bool cmp1(const A &x,const A &y) {return x.z<y.z;}
  15. bool cmp2(const A &x,const A &y) {return x.id<y.id;}
  16. int find(int x) {
  17. return f[x]==x?x:f[x]=find(f[x]);
  18. }
  19. inline void add(int u,int v,int w) {
  20. to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
  21. }
  22. void dfs1(int x,int y) {
  23. int i;
  24. dep[x]=dep[y]+1; fa[x]=y; siz[x]=1;
  25. for(i=head[x];i;i=nxt[i]) {
  26. if(to[i]!=y) {
  27. ref[val[i]]=to[i];
  28. dfs1(to[i],x); siz[x]+=siz[to[i]];
  29. if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
  30. }
  31. }
  32. }
  33. void dfs2(int x,int t) {
  34. top[x]=t;idx[x]=++tot;
  35. if(son[x]) dfs2(son[x],t);
  36. int i;
  37. for(i=head[x];i;i=nxt[i]) {
  38. if(to[i]!=fa[x]&&to[i]!=son[x]) {
  39. dfs2(to[i],to[i]);
  40. }
  41. }
  42. }
  43. void update(int l,int r,int x,int y,int v,int p) {
  44. if(x<=l&&y>=r) {
  45. mn[p]=min(mn[p],v); return ;
  46. }
  47. int mid=(l+r)>>1;
  48. if(x<=mid) update(l,mid,x,y,v,ls);
  49. if(y>mid) update(mid+1,r,x,y,v,rs);
  50. }
  51. int query(int l,int r,int x,int p) {
  52. if(l==r) return mn[p];
  53. int mid=(l+r)>>1;
  54. if(x<=mid) return min(mn[p],query(l,mid,x,ls));
  55. else return min(mn[p],query(mid+1,r,x,rs));
  56. }
  57. int main() {
  58. scanf("%d%d",&n,&m);
  59. int i,ne=0,x,y;
  60. for(i=1;i<=n;i++) f[i]=i;
  61. for(i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z),a[i].id=i;
  62. sort(a+1,a+m+1,cmp1);
  63. for(i=1;i<=m;i++) {
  64. int dx=find(a[i].x),dy=find(a[i].y);
  65. if(dx!=dy) {
  66. add(a[i].x,a[i].y,a[i].id);
  67. add(a[i].y,a[i].x,a[i].id);
  68. ne++;
  69. f[dx]=dy;
  70. a[i].flg=1;
  71. sum+=a[i].z;
  72. if(ne==n-1) break;
  73. }
  74. }
  75. int q;
  76. if(ne<n-1) {
  77. scanf("%d",&q);
  78. while(q--) {
  79. puts("Not connected");
  80. }
  81. return 0;
  82. }
  83. dfs1(1,0); dfs2(1,1);
  84. for(i=1;i<=4*n;i++) mn[i]=1<<30;
  85. sort(a+1,a+m+1,cmp2);
  86. for(i=1;i<=m;i++) {
  87. if(!a[i].flg) {
  88. x=a[i].x,y=a[i].y;
  89. while(top[x]!=top[y]) {
  90. if(dep[top[x]]>dep[top[y]]) swap(x,y);
  91. update(1,n,idx[top[y]],idx[y],a[i].z,1);
  92. y=fa[top[y]];
  93. }
  94. if(dep[x]<dep[y]) swap(x,y);
  95. if(x!=y)update(1,n,idx[y]+1,idx[x],a[i].z,1);
  96. }
  97. }
  98. int k;
  99. scanf("%d",&q);
  100. while(q--) {
  101. scanf("%d",&k);
  102. if(!a[k].flg) {
  103. printf("%d\n",sum);
  104. }else {
  105. x=a[k].x;y=a[k].y;
  106. int re=query(1,n,idx[ref[k]],1);
  107. if(re==(1<<30)) {
  108. puts("Not connected");
  109. }else {
  110. printf("%d\n",sum-a[k].z+re);
  111. }
  112. }
  113. }
  114. }

BZOJ_2238_Mst_树剖+线段树的更多相关文章

  1. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  2. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

  3. 【BZOJ5210】最大连通子块和 树剖线段树+动态DP

    [BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...

  4. [LNOI2014]LCA(树剖+线段树)

    \(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...

  5. [CF1007D]Ants[2-SAT+树剖+线段树优化建图]

    题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...

  6. LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)

    题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...

  7. BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)

    传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...

  8. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  9. 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 ...

随机推荐

  1. 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- ...

  2. [ SSH框架 ] Hibernate框架学习之四(JPA)

    一.JPA概述以及它和Hibernate之间的关系 1.1.Hibernate 概述 JPA Java Persistence API,是EJB3规范中负责对象持久化的应用程序编程接口(ORM接口), ...

  3. ERR_NAME_NOT_RESOLVED错误的解决

    参考:http://zhidao.baidu.com/link?url=-Beq80OXoSKef_9SmGXkQHvq2AkSE0aGfac02ykorglQF6JTP7F1XNtVxFn9EMfn ...

  4. MySQL 的索引优化

    索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的IO成本.MySQL在300万条记录左右性能开始逐渐下降,虽然官方文档说500~800w记录,所以大数据量建立索引是非常有必要的.My ...

  5. ThinkPHP5从零基础搭建CMS系统(二)

    接上节,开启wamp集成环境,在浏览器地址栏输入http://localhost/cms/public,即可运行项目,但是这边域名太长,做一下处理. 注:需要查看tp5全部教程,请点击右侧thinkp ...

  6. NewLife.Net——管道处理器解决粘包

    Tcp网络编程,必须要解决的一个问题就是粘包,尽管解决办法有很多,这里讲一个比较简单的方法. 老规矩,先上代码:https://github.com/nnhy/NewLife.Net.Tests 一. ...

  7. Python 3 利用 Dlib 19.7 实现摄像头人脸识别

    0.引言 利用python开发,借助Dlib库捕获摄像头中的人脸,提取人脸特征,通过计算欧氏距离来和预存的人脸特征进行对比,达到人脸识别的目的: 可以自动从摄像头中抠取人脸图片存储到本地: 根据抠取的 ...

  8. HTML学习笔记7:图片与超链接

    ①图片       <img/>标签,属性有: src,图片链接,分绝对路径和相对路径 width宽度 height,高度   ②超链接     <a>    内容描述     ...

  9. SSH密钥认证添加方法和一些实用配置

    更改SSH端口号 用账号密码进入主机 sudo nano /etc/ssh/sshd-config 再其中添加Port 22等或改变该条 添加公钥到主机 cd ~ sudo mkdir .ssh 此处 ...

  10. 【python3】如何建立爬虫代理ip池

    一.为什么需要建立爬虫代理ip池 在众多的网站防爬措施中,有一种是根据ip的访问频率进行限制的,在某段时间内,当某个ip的访问量达到一定的阀值时,该ip会被拉黑.在一段时间内被禁止访问. 这种时候,可 ...