题面

Description

给你一个城市下水道网络图,你需要选出一些管道,使得在只使用这些管道的情况下,令整个网络联通,并且花费最小。

网络图可以看做是无向连通图,有nnn个节点和mmm条边,每条边连接uiu_iui​和viv_ivi​,选择的花费是wiw_iwi​。

不巧的是,由于某些原因,现在市政局要求选定某条特定的边管道,你的任务是求出对于某一条边,在选择这条管道的前提下的最小花费。

Input

第111行包含两个整数nnn,mmm,表示点数和边数。

第222~m+1m+1m+1行每行三个整数uiu_iui​,viv_ivi​,wiw_iwi​,表示有一条管道连接uiu_iui​和viv_ivi​,费用为wiw_iwi​。

Output

输出m行,每行一个整数,表示选择第i条管道的前提下的最小花费。

管道按输入的顺序编号为111~mmm。

Sample Input

5 7
1 2 3
1 3 1
1 4 5
2 3 2
2 5 3
3 4 2
4 5 4

Sample Output

9
8
11
8
8
8
9

Hint

对于20%20\%20%的数据,n&lt;=1000n&lt;=1000n<=1000,m&lt;=2000m&lt;=2000m<=2000

对于另外20%20\%20%的数据,m&lt;=n+10m&lt;=n+10m<=n+10

对于100%100\%100%的数据,2&lt;=ui,vi&lt;=n&lt;=1000002&lt;=u_i,v_i&lt;=n&lt;=1000002<=ui​,vi​<=n<=100000,1&lt;=m&lt;=2000001&lt;=m&lt;=2000001<=m<=200000,wi&lt;=231w_i&lt;=2^{31}wi​<=231

保证初始图连通。

题解

题目就是求包含某条边的最小生成树。

先把原图的最小生成树求出来。

枚举图上的每一条边,考虑选择这条管道的前提下的最小花费:

  1. 如果这条边就在最小生成树上,显然,最小花费就是最小生成树的边权和。

  2. 如果这条边不在最小生成树上,如下图中的边(5,6)(5,6)(5,6):

    显然如果我们加入了边(5,6)(5,6)(5,6),就会构成一个环,这个环的一部分就是(5,6)(5,6)(5,6),另一部分是在树上的555到666的路径,即5⟶3⟶4⟶65\longrightarrow3\longrightarrow4\longrightarrow65⟶3⟶4⟶6。

    这样如果我们去掉环上的任意一条边,所有点还是联通的,且边权和比没去时更小。

    又因为我们不能去掉边(5,6)(5,6)(5,6),所以我们只能去掉原图的最小生成树上的555到666的路径的任意一边。

    且为了保证去掉这条边后边权和最小,我们要去掉这条路径上边权最大的边。

这样两种情况都讨论完了,至于第二种情况的路径上边权最大值怎么维护,可以用树剖或者倍增。

代码如下:

#include<bits/stdc++.h>#define N 1000010
#define M 2000010
#define int long long
#define ll long longusing namespace std;struct edge
{int u,v,w,id;
}e[M];int n,m,fa[N];
int f[N][20],maxn[N][20],d[N];
int cnt,head[N],nxt[N<<1],to[N<<1],w[N<<1];
ll ans,Ans[N];
bool flag[N];inline int read()
{int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^'0');ch=getchar();}return x*f;
}int find(int x)
{if(x==fa[x])return x;return fa[x]=find(fa[x]);
}inline bool cmp(edge a,edge b)
{return a.w<b.w;
}inline void adde(int u,int v,int wi)
{to[++cnt]=v;w[cnt]=wi;nxt[cnt]=head[u];head[u]=cnt;
}void dfs(int u)
{for(int i=1;i<=18;i++)//倍增数组{f[u][i]=f[f[u][i-1]][i-1];maxn[u][i]=max(maxn[u][i-1],maxn[f[u][i-1]][i-1]);}for(int i=head[u];i;i=nxt[i]){if(to[i]!=f[u][0]){f[to[i]][0]=u;maxn[to[i]][0]=w[i];d[to[i]]=d[u]+1;dfs(to[i]);}}
}inline int LCA(int a,int b)//a->lca->b
{int maxx=0;if(d[a]<d[b])swap(a,b);for(int i=18;i>=0;i--)if(d[f[a][i]]>=d[b])  maxx=max(maxx,maxn[a][i]),a=f[a][i];if(a==b)return maxx;for(int i=18;i>=0;i--){if(f[a][i]!=f[b][i]){maxx=max(maxx,max(maxn[a][i],maxn[b][i]));a=f[a][i],b=f[b][i];}}maxx=max(maxx,max(maxn[a][0],maxn[b][0]));return maxx;
}signed main()
{n=read(),m=read();for(register int i=1;i<=n;i++)fa[i]=i;for(register int i=1;i<=m;i++){e[i].u=read(),e[i].v=read(),e[i].w=read();e[i].id=i;}sort(e+1,e+m+1,cmp);for(register int i=1,num=0;i<=m;i++)//最小生成树{if(num==n-1)break;int a=find(e[i].u),b=find(e[i].v);if(a!=b){fa[a]=b;adde(e[i].u,e[i].v,e[i].w);adde(e[i].v,e[i].u,e[i].w);ans+=e[i].w;flag[i]=true;num++;}}d[1]=1;dfs(1);for(register int i=1;i<=m;i++){if(flag[i])//这条边在最小生成树{Ans[e[i].id]=ans;continue;}int maxx=LCA(e[i].u,e[i].v);//不在就求u、v路径上的边权最大值Ans[e[i].id]=ans-maxx+e[i].w;}for(register int i=1;i<=m;i++)printf("%lld\n",Ans[i]);return 0;
}

另,相似题:XSY2485,以及题解。

【XSY2515】管道(pipe)(最小生成树+倍增lca)相关推荐

  1. 【XSY2485】MST(最小生成树+倍增lca+并查集)

    题面 Description 给定一个nnn个点mmm条边的连通图,保证没有自环和重边.对于每条边求出,在其他边权值不变的情况下,它能取的最大权值,使得这条边在连通图的所有最小生成树上.假如最大权值为 ...

  2. HDU - 3078 Network 倍增LCA

    倍增lca,把路径上点全部拉出来拍个序输出第k大就过了. 不知道怎么过的,咱也不敢问. #include<stdio.h> #include<string.h> #includ ...

  3. BZOJ 2144 跳跳棋(神仙建模题,倍增 LCA,二分)【BZOJ修复工程】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2144 是 hydro 的 BZOJ ...

  4. linux操作系统进程间通信IPC之管道pipe及FIFO

    linux环境下,各进程相互独立,如果想要交换两个进程之间的数据,需要通过内核,在内存中提供一个缓存区,一个进程往缓存区中写数据,一个往缓存区读数据,内核提供的这种机制称为进程间通信(IPC),常见的 ...

  5. 无名管道pipe使用方法

    有名管道pipe函数:int pipe(int filedes[2]);  下面程序通过创建进程,父进程写入数据,子进程读取数据,从管道中读取数据. #include <stdio.h> ...

  6. [转]Angular2 使用管道Pipe以及自定义管道格式数据

    本文转自:https://www.pocketdigi.com/20170209/1563.html 管道(Pipe)可以根据开发者的意愿将数据格式化,还可以多个管道串联. 纯管道(Pure Pipe ...

  7. 洛谷T1967 货车运输 Kruskal最大生成树倍增LCA

    这题的题意是:对于每组x.y,求x到y路径上最小边权的最大值. 于是可以使用最大生成树,因为最大生成树满足性质:生成树中最小边权最大,且任意两点间路径上最小边权最大. 有了树之后,要求路径,那就要考虑 ...

  8. python 归纳 (二二)_多进程数据共享和同步_管道Pipe

    # -*- coding: utf-8 -*- """ 多进程数据共享 管道Pipe逻辑:2个进程,各自发送数据到管道,对方从管道中取到数据总结:1.只适合两个进程2.r ...

  9. [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)

    4568: [Scoi2016]幸运数字 Time Limit: 60 Sec  Memory Limit: 256 MB Submit: 2131  Solved: 865 [Submit][Sta ...

最新文章

  1. 安卓相对布局常用语句
  2. 首长,Redis性能优化十三条军规立好了,请过目~
  3. 深度学习中的激活函数总结
  4. 小米平板2第三方rom_【2020年1月10日更新】小米手机全系列设备代号一览
  5. Ubuntu18.04安装Scala
  6. 深入理解IIS的多线程工作机制
  7. 《七哥说道》第五章:入职惨做苦力,画饼一望无际
  8. 如何向Mac Dictionary App添加其他语言
  9. 当Python遇上HDF5--性能优化实战
  10. 财税打印机LQ 670K+ win10驱动
  11. 园林计算机制图在计算机上的应用,园林计算机制图
  12. 苹果手机页面不兼容问题——mui
  13. Java飞机小游戏代码详解
  14. AWS中IGW,NAT GW以及Egress-only IGW的概念和区别
  15. SQL数据修复,SQL数据库修复,SQL数据库修复软件,SQL数据库恢复,SQL数据库日志恢复软件
  16. [收藏]基于Spark Graphframes的社交关系图谱项目实战
  17. Field communityMapper in com.estate.service.impl.CommunityServiceImpl required a bean of type ‘
  18. (一)城市三维基础展示方案
  19. 计算机的工作原理是二进制原理吗,计算机是怎么通过二进制原理来工作的?
  20. 【板栗糖GIS】在测绘项目中——比例尺和分辨率的区别

热门文章

  1. 交通 流量 时间序列预测,神经网络 机器学习 BPNN
  2. Computer Vision_2_Active Shape Models:Active Shape Models-Their Training and Application——1995
  3. org.apache.solr.client.solrj.impl.CloudSolrServer$RouteException: Exception writing document id xxxx
  4. Linux 如何检测硬盘坏道?
  5. 这可能是JAVA程序员进阶架构师的最佳之路了 !
  6. 记忆化搜索例题 记忆化搜索
  7. 基于Android的社交游戏百宝箱App设计与实现
  8. Py西游攻关之正则表达式
  9. 【SpringMVC】@RequestMapping和@GetMapping的区别
  10. oracle报错解决