Description

Link.

修改边权的动态 MST。

Solution

讲清楚点。

修改边权的 MST,考虑对时间分治。设我们当前操作的操作区间是 \([l,r]\),直接暴力找 MST 是不行的。

考虑找出必要的边和必不要的边。

  • 若把 \([l,r]\) 操作中的边边权改成 \(+\infty\),拿原图点集和不包含 \([l,r]\) 中边的边集和 \([l,r]\) 中边权修改为 \(+\infty\) 后的边的集合的并集作为边集跑 MST,此时如果不在 MST 上的边一定不在最终的 MST 边集中。

  • 同理,改成 \(-\infty\),此时在 MST 边集里的边一定在最终的 MST 边集中。

这样暴力跑 Kruskal 的规模保证在了 \(O(r-l+1)\)。

复杂度 \(O(n\log_{2}^{2}n)\)。

  1. #include<bits/stdc++.h>
  2. const int INF=std::numeric_limits<int>::max();
  3. struct edge
  4. {
  5. int fr,ba,val,ID;
  6. edge():fr(0),ba(0),val(0),ID(0){}
  7. edge(int _fr,int _ba,int _val,int _id):fr(_fr),ba(_ba),val(_val),ID(_id){}
  8. friend bool operator < (const edge &lhs,const edge &rhs){return lhs.val<rhs.val;}
  9. }edge_set[20][100010],ori_edge[100010],tmp_edge[100010];
  10. struct oper
  11. {
  12. int ID,val;
  13. oper():ID(0),val(0){}
  14. oper(int _id,int _val):ID(_id),val(_val){}
  15. }ope[100010];
  16. int tagcur[100010],tagope[100010],n,m,q,size_v[20],size_e[20],ver_set[20][100010],wgt[100010],srt[100010];
  17. struct DSU
  18. {
  19. int fa[100010];
  20. int f(int i){return fa[i];}
  21. void clear(int l){std::iota(fa+1,fa+l+1,1);}
  22. int find(int x){return (x^fa[x])?fa[x]=find(fa[x]):x;}
  23. bool merge(int x,int y){x=find(x),y=find(y); if(x^y) return fa[x]=y,true; else return false;}
  24. }dsu;
  25. int read()
  26. {
  27. int x=0,f=1;
  28. char c=getchar();
  29. while(c<'0' || c>'9')
  30. {
  31. if(c=='-') f=-1;
  32. c=getchar();
  33. }
  34. while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^'0'),c=getchar();
  35. if(~f) return x;
  36. else return -x;
  37. }
  38. int wrstk[100];
  39. void write(long long x,char las='\n')
  40. {
  41. int top=0;
  42. if(x<0) x=-x,putchar('-');
  43. do wrstk[++top]=x%10,x/=10; while(x);
  44. while(top) putchar(wrstk[top--]^'0');
  45. putchar(las);
  46. }
  47. void rawgrass(int l,int r,int dep,long long ans)
  48. {
  49. const int &n=size_v[dep],&m=size_e[dep];
  50. if(l^r)
  51. {
  52. for(int i=1;i<=m;++i) tagope[edge_set[dep][i].ID]=0;
  53. for(int i=l;i<=r;++i) tagcur[ope[i].ID]=1;
  54. for(int i=1;i<=m;++i)
  55. {
  56. tmp_edge[i]=edge_set[dep][i];
  57. if(tagcur[tmp_edge[i].ID]) tmp_edge[i].val=INF;
  58. }
  59. std::sort(tmp_edge+1,tmp_edge+m+1);
  60. dsu.clear(n);
  61. for(int i=1;i<=m;++i) if(!dsu.merge(tmp_edge[i].fr,tmp_edge[i].ba) && tmp_edge[i].val!=INF) tagope[tmp_edge[i].ID]=-1;
  62. for(int i=l;i<=r;++i) tagcur[ope[i].ID]=1;
  63. for(int i=1;i<=m;++i)
  64. {
  65. tmp_edge[i]=edge_set[dep][i];
  66. if(tagcur[tmp_edge[i].ID]) tmp_edge[i].val=-INF;
  67. }
  68. std::sort(tmp_edge+1,tmp_edge+m+1);
  69. dsu.clear(n);
  70. for(int i=1;i<=m;++i) if(dsu.merge(tmp_edge[i].fr,tmp_edge[i].ba) && tmp_edge[i].val!=-INF) tagope[tmp_edge[i].ID]=1;
  71. for(int i=l;i<=r;++i) tagcur[ope[i].ID]=0;
  72. size_v[dep+1]=size_e[dep+1]=0;
  73. dsu.clear(n);
  74. for(int i=1;i<=m;++i) if(tagope[edge_set[dep][i].ID]==1) dsu.merge(edge_set[dep][i].fr,edge_set[dep][i].ba);
  75. for(int i=1;i<=n;++i) if(dsu.f(i)==i) ver_set[dep+1][++size_v[dep+1]]=ver_set[dep][i],srt[i]=size_v[dep+1];
  76. for(int i=1;i<=m;++i)
  77. {
  78. if(tagope[edge_set[dep][i].ID]==1) ans+=edge_set[dep][i].val;
  79. else if(tagope[edge_set[dep][i].ID]==0)
  80. {
  81. int x=edge_set[dep][i].fr,y=edge_set[dep][i].ba;
  82. x=dsu.find(x),y=dsu.find(y);
  83. if(x^y) edge_set[dep+1][++size_e[dep+1]]=edge(srt[x],srt[y],edge_set[dep][i].val,edge_set[dep][i].ID);
  84. }
  85. }
  86. int mid=(l+r)>>1;
  87. rawgrass(l,mid,dep+1,ans);
  88. for(int i=l;i<=mid;++i) wgt[ope[i].ID]=ope[i].val;
  89. for(int i=1;i<=size_e[dep+1];++i) if(wgt[edge_set[dep+1][i].ID]!=INF) edge_set[dep+1][i].val=wgt[edge_set[dep+1][i].ID];
  90. for(int i=l;i<=mid;++i) wgt[ope[i].ID]=INF;
  91. rawgrass(mid+1,r,dep+1,ans);
  92. }
  93. else
  94. {
  95. for(int i=1;i<=m;++i)
  96. {
  97. tmp_edge[i]=edge_set[dep][i];
  98. if(tmp_edge[i].ID==ope[l].ID) tmp_edge[i].val=ope[l].val;
  99. }
  100. std::sort(tmp_edge+1,tmp_edge+m+1);
  101. dsu.clear(n);
  102. for(int i=1;i<=m;++i) if(dsu.merge(tmp_edge[i].fr,tmp_edge[i].ba)) ans+=tmp_edge[i].val;
  103. write(ans);
  104. }
  105. }
  106. int main()
  107. {
  108. n=read(),m=read(),q=read();
  109. for(int i=1,x,y,z;i<=m;++i) x=read(),y=read(),z=read(),ori_edge[i]=edge(x,y,z,i);
  110. for(int i=1,id,k;i<=q;++i) id=read(),k=read(),ope[i]=oper(id,k);
  111. size_v[0]=n;
  112. size_e[0]=m;
  113. for(int i=1;i<=size_v[0];++i) ver_set[0][i]=i;
  114. for(int i=1;i<=size_e[0];++i) edge_set[0][i]=ori_edge[i],wgt[i]=INF;
  115. rawgrass(1,q,0,0);
  116. return 0;
  117. }

Solution -「HNOI 2010」城市建设的更多相关文章

  1. Solution -「HNOI 2009」「洛谷 P4727」图的同构计数

    \(\mathcal{Description}\)   Link.   求含 \(n\) 个点的无标号简单无向图的个数,答案模 \(997\). \(\mathcal{Solution}\)   首先 ...

  2. Solution -「HNOI 2019」「洛谷 P5293」白兔之舞

    \(\mathcal{Description}\)   Link.   不想概括题意.jpg \(\mathcal{Solution}\)   定义点集 \(S_c=\{(u,v)|v=c\}\):第 ...

  3. Solution -「POI 2010」「洛谷 P3511」MOS-Bridges

    \(\mathcal{Description}\)   Link.(洛谷上这翻译真的一言难尽呐.   给定一个 \(n\) 个点 \(m\) 条边的无向图,一条边 \((u,v,a,b)\) 表示从 ...

  4. Solution -「HNOI 2007」「洛谷 P3185」分裂游戏

    \(\mathcal{Description}\)   Link.   给定 \(n\) 堆石子,数量为 \(\{a_n\}\),双人博弈,每轮操作选定 \(i<j\le k\),使 \(a_i ...

  5. LOJ#3054. 「HNOI 2019」鱼

    LOJ#3054. 「HNOI 2019」鱼 https://loj.ac/problem/3054 题意 平面上有n个点,问能组成几个六个点的鱼.(n<=1000) 分析 鱼题,劲啊. 容易想 ...

  6. Solution -「ARC 104E」Random LIS

    \(\mathcal{Description}\)   Link.   给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...

  7. Solution -「JOISC 2021」「LOJ #3491」道路建设

    \(\mathcal{Description}\)   Link.   平面上有 \(n\) 个互不重合的点 \((x_{1..n},y_{1..n})\),求其两两曼哈顿距离的前 \(m\) 小值. ...

  8. Solution -「JOISC 2019」「LOJ #3036」指定城市

    \(\mathcal{Description}\)   Link.   给定一棵含 \(n\) 个结点的树,双向边权不相同.\(q\) 次询问,每次询问在树上标记 \(e\) 个点,标记的价值为所有趋 ...

  9. Solution -「HNOI」EVACUATE

    Sol. 可以发现人的移动除了不能穿墙以外没有别的限制.也就是说人的移动多半不是解题的突破口. 接下来会发现出口的限制很强,即出口每个时刻只能允许一个人出去. 每个时刻? 不难想到对于每一个时刻每一个 ...

  10. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

随机推荐

  1. 【建议收藏】Log4j配置详解

    大家在日常开发中必然会使用到日志组件,Log4j是Java方向上比较常用的日志组件,今天给大家分享下Log4j支持的配置项,强烈建议收藏,以便配置时查看 #展示log4j各种配置,私有部分见文件中注释 ...

  2. ESP8266-01S烧录固件

    ESP8266-01S 整理了一下ESP01S的烧录固件和烧录APP 链接:https://pan.baidu.com/s/1DApOQcWhqvk378ZklJSypA 提取码:1028 文件夹包含 ...

  3. LeetCode 周赛 350(2023/06/18)01 背包变型题

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 [BaguTree Pro] 知识星球提问. 往期回顾:LeetCode 单周赛第 348 场 · 数位 DP ...

  4. 前端Vue自定义询问弹框和输入弹框

    前端Vue自定义询问弹框和输入弹框, 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13119 效果图如下: 使用方法 < ...

  5. rabbitmq安装部署和常用命令

    python操作rabbitmq rabbitmq实现可以使用java或者springboot的封装方法,自己创建实现,也可以使用中间件实现,相对于自建,使用rabbitmq应用场景及使用更系统安全. ...

  6. 如何使用libavfilter库给输入文件input.yuv添加视频滤镜?

    一.视频滤镜初始化 本次代码实现的是给输入视频文件添加水平翻转滤镜,在视频滤镜初始化部分我们可以分为以下几步进行: 1.创建滤镜图结构 视频滤镜功能最核心的结构为滤镜图结构,即AVFilterGrap ...

  7. Pycharm里Python运行窗口显示乱码���的解决方法

    当你的Python程序运行后,会在运行窗口中显示乱码 ��� 等字样,如下 原因是 Pycharm中默认设置只显示UTF-8编码的格式,需要修改支持显示中文支持. 解决方法: 菜单中选择 File S ...

  8. Linux 日志服务管理

    日志管理 1 系统日志管理 1 rsyslog系统日志服务 日志记录的内容包括: 历史事件:时间,地点,人物,事件 Jul 18 14:30:53 # 时间 ubuntu2204 # 地点 (在哪个主 ...

  9. python 镜像

    https://pypi.douban.com/simple/   豆瓣源 pip install -i https://pypi.douban.com/simple/ pymysql # pymys ...

  10. openpyxl 统一表格样式

    # 统一表格样式 rows = ws.max_row columns = ws.max_column # print(rows) # print(columns) for row in range(1 ...