题面

Description

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

Input

第一行两个整数nnn,mmm,表示nnn个点mmm条边

接下来mmm行,每行333个整数xxx,yyy,zzz,表示节点xxx和节点yyy之间有一条长zzz的边。

Output

输出一行mmm个整数,表示每条边的答案

Sample Input

4 4
1 2 2
2 3 2
3 4 2
4 1 3

Sample Output

2 2 2 1

HINT

对于30%30\%30%的数据1≤n≤1031≤n≤10^31≤n≤103,1≤m≤3×1031≤m≤3\times10^31≤m≤3×103

对于100%100\%100%的数据1≤n,m≤2×1051≤n,m≤2\times 10^51≤n,m≤2×105,1≤z≤1091≤z≤10^91≤z≤109

题解

(来自XSY的solution)

先求出图的一棵最小生成树:

对于不在树上的边(x,y)(x,y)(x,y), 它的权值只要小于树上xxx到yyy路径中一条边就可以代替这条边。

对于在树上的边(x,y)(x,y)(x,y),可以先预处理出所有两端在xxx到yyy路径上的不在树上的边的最小值。它的权值一定要小于最小值。

路径maxmaxmax和minminmin都可以用倍增求。

时间复杂度O(nlogn)O(nlogn)O(nlogn)。

代码:

#include<bits/stdc++.h>#define N 200010
#define M127 2139062143using namespace std;struct edge
{int u,v,w,id;
}e[N];int n,m,fa[N],ans[N];
int cnt,head[N],to[N<<1],nxt[N<<1],w[N<<1],id[N<<1];
int f[N][20],maxn[N][20],from[N],d[N];
bool flag[N];void adde(int u,int v,int wi,int idi)
{to[++cnt]=v;w[cnt]=wi;id[cnt]=idi;nxt[cnt]=head[u];head[u]=cnt;
}bool cmp(edge a,edge b)
{return a.w<b.w;
}int find(int x)
{if(fa[x]!=x)return fa[x]=find(fa[x]);return x;
}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];from[to[i]]=id[i];d[to[i]]=d[u]+1;dfs(to[i]);}}
}int getMax(int a,int b,int &lca)
{int ans=0;if(d[a]<d[b])swap(a,b);for(int i=18;i>=0;i--){if(d[f[a][i]]>=d[b]){ans=max(ans,maxn[a][i]);a=f[a][i];}}if(a==b){lca=a;return ans;}for(int i=18;i>=0;i--){if(f[a][i]!=f[b][i]){ans=max(ans,maxn[a][i]);ans=max(ans,maxn[b][i]);a=f[a][i],b=f[b][i]; }}lca=f[a][0];return max(ans,max(maxn[a][0],maxn[b][0]));
}void solve(int u,int lca,int wi)
{u=find(u);while(d[u]>d[lca]){ans[from[u]]=min(ans[from[u]],wi-1);fa[u]=find(f[u][0]);u=find(u);}
}int main()
{memset(ans,127,sizeof(ans));scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)fa[i]=i;for(int i=1;i<=m;i++){scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);e[i].id=i;}sort(e+1,e+m+1,cmp);for(int i=1,tot=0;i<=m;i++){if(tot==n-1)break;int x=find(e[i].u);int y=find(e[i].v);if(x!=y){fa[y]=x;adde(e[i].u,e[i].v,e[i].w,e[i].id);adde(e[i].v,e[i].u,e[i].w,e[i].id);flag[i]=true;tot++;}}dfs(1);for(int i=1;i<=n;i++)fa[i]=i;for(int i=1;i<=m;i++){if(!flag[i]){int lca;ans[e[i].id]=getMax(e[i].u,e[i].v,lca)-1;solve(e[i].u,lca,e[i].w);solve(e[i].v,lca,e[i].w);}}for(int i=1;i<=m;i++){if(ans[i]==M127)printf("-1 ");else printf("%d ",ans[i]);}return 0;
}

【XSY2485】MST(最小生成树+倍增lca+并查集)相关推荐

  1. mst算法matlab_基于并查集+Kruskal算法的matlab程序及最小生成树绘图

    学了一天最小生成树,稍稍总结一下,这是第一篇 kruskal算法 关于kruskal算法已有大量的资料,不再赘述,算法流程为: 得到邻接矩阵和权值: 初始化,连接距离最小的两点: 连接距离次小的两点, ...

  2. 51nod1743-雪之国度【最小生成树,LCA,并查集】

    正题 题目链接:http://www.51nod.com/Challenge/Problem.html#problemId=1743 题目大意 nnn个点mmm条边的一张图,每次询问要求找出x,yx, ...

  3. POJ - 3694 Network(边双缩点+LCA+并查集优化)

    题目链接:点击查看 题目大意:给出一个由n个点组成的无向图,现在有m次操作,每次操作都会向图中增加一条无向边,每次操作后询问当前图中有多少个桥 题目分析:题意很好理解,思路也很好想,就是代码量有点小多 ...

  4. POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)

    [题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...

  5. 【割边缩点】解题报告:POJ - 3694 - Network(Tarjan割边缩点 + LCA + 并查集优化)

    POJ - 3694 - Network 给定一张N个点M条边的无向连通图,然后执行Q次操作,每次向图中添加一条边,并且询问当前无向图中"桥"的数量.N≤105,M≤2∗105,Q ...

  6. POJ 3694 (tarjan缩点+LCA+并查集)

    好久没写过这么长的代码了,题解东哥讲了那么多,并查集优化还是很厉害的,赶快做做前几天碰到的相似的题. 1 #include <iostream> 2 #include <algori ...

  7. 最小生成树kruskal算法并查集版 C语言实现

    今天数据结构课讲了最小生成树的Kruskal算法和Prim算法,不过都只是概念,可能是怕他们听不懂吧,反正算法实现一概不讲...囧 下午抱着<算法导论>跑去图书馆看Kruskal算法,发现 ...

  8. 最小生成树KrusKal算法(并查集)

    洛谷p1111链接 克鲁斯卡尔算法的思路就是由森林变成树的过程,其中最主要的就是贪心和并查集的应用. 我们知道链接n个点需要n-1条边,这就满足的最后生成的是一颗树,而不是一个环.在这n-1条边的选择 ...

  9. 最小生成树Kruskal算法+并查集检查连通

    /* 10 6 1 2 6 1 3 1 1 4 5 2 3 5 2 5 3 3 4 5 3 5 6 3 6 4 4 6 2 5 6 6 */// 本例解决最小生成树问题 // 并查集来加快效率 // ...

最新文章

  1. Ubuntu下安装中文输入法(本文安装的搜狗输入法)
  2. 微信小程序-学习笔记6-组件
  3. release 无法打开windows.h vs_Windows 10 Build 21270发布:Cortana新增打开/搜索文件技能...
  4. Approximate Nearest Neighbors.接近最近邻搜索
  5. 如何清除tomcat缓存
  6. C++——override
  7. 遇到代码缺陷不要慌,马上教你快速检测和修复
  8. 短文本合并重复(去重)的简单有效做法
  9. bagging和时间序列预测_Simple RNN时间序列预测
  10. HCIE-Security Day38:理论学习:信息安全管理
  11. 第三章 python流程控制
  12. VS2017 CUDA编程学习实例1:CUDA实现向量点乘
  13. 自动控制原理3.3---二阶系统的时域分析
  14. C# 在Word文档中生成条形码
  15. python3 get函数,python3请求的GET方法
  16. 【模糊综合评价的运用】——《电子舌技术在食用盐模糊感官评价中的应用》论文笔记(内附MATLAB程序)
  17. ubuntunbsp;16.04安装smba服务
  18. Solana 基金会与韩国区块链孵化器 ROK Capital 合作推出 2000 万美元生态基金
  19. (华师)CSMA技术的P—坚持算法规则是什么?
  20. 一曲清商 满墨柔情不知数

热门文章

  1. MySQL: 彻底删除数据库
  2. 个人电脑详细的安全设置方法
  3. 【游戏设计模式】之 《游戏编程模式》全书内容提炼总结
  4. 图卷积(1)——从欧式空间到非欧式空间
  5. canvas图片绘制-两张图片的叠加
  6. SVD分解图像压缩应用英语论文
  7. linux安全(1)
  8. windows.edb文件过大,导致c盘空间极小问题
  9. 关于华擎J3455安装虚拟机PVE和ESXI还有作为纯物理黑群晖的一些事宜
  10. GPRS网络组成及接口