cf827D Best Edge Weight (kruskal+倍增lca+并查集)
先用kruskal处理出一个最小生成树
对于非树边,倍增找出两端点间的最大边权-1就是答案
对于树边,如果它能被替代,就要有一条非树边,两端点在树上的路径覆盖了这条树边,而且边权不大于这条树边
这里可以树剖来做,但是不想用..
如果先把非树边从小到大排序然后去覆盖树边,那么一条树边只需要被覆盖一次
所以可以用一个并查集来把父子边被覆盖的点合到一起,在合并之前记下来这次覆盖的边权,下次再覆盖的时候直接跳过去就可以
#include<bits/stdc++.h>
#define pa pair<int,int>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=2e5+,inf=1e9+; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} struct Edge{
int a,b,l,ne;
bool used;
}eg[maxn],eg2[maxn*];
int egh[maxn],ect;
int N,M,fa[maxn][],bf[maxn],bm[maxn],ma[maxn][],dep[maxn];
int ans[maxn]; inline int getf(int x){return bf[x]==x?x:bf[x]=getf(bf[x]);}
inline bool cmp(Edge a,Edge b){return a.l<b.l;}
inline void adeg(int a,int b,int c){
eg2[++ect].b=b;eg2[ect].ne=egh[a];
eg2[ect].l=c,egh[a]=ect;
} void dfs(int x){
// printf("!!%d %d %d\n",x,fa[x][0],ma[x][0]);
for(int i=;fa[x][i]&&fa[fa[x][i]];i++)
fa[x][i+]=fa[fa[x][i]][i],ma[x][i+]=max(ma[x][i],ma[fa[x][i]][i]);
for(int i=egh[x];i;i=eg2[i].ne){
int b=eg2[i].b;
if(b==fa[x][]) continue;
ma[b][]=eg2[i].l;
fa[b][]=x;dep[b]=dep[x]+;
dfs(b);
}
} int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
int re=;
for(int i=log2(dep[x]-dep[y]);i>=&&dep[x]!=dep[y];i--){
if(fa[x][i]&&dep[fa[x][i]]>=dep[y])
re=max(re,ma[x][i]),x=fa[x][i];
}
if(x==y) return re;
for(int i=log2(dep[x]);i>=;i--){
if(fa[x][i]!=fa[y][i])
re=max(re,max(ma[x][i],ma[y][i])),x=fa[x][i],y=fa[y][i];
}
return max(re,max(ma[x][],ma[y][]));
} int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd(),M=rd();
for(i=;i<=M;i++){
eg[i].a=rd(),eg[i].b=rd(),eg[i].l=rd();
eg[i].ne=i;
}
sort(eg+,eg+M+,cmp);
for(i=;i<=N;i++) bf[i]=i;
for(i=,j=;i<=M&&j<N-;i++){
int a=getf(eg[i].a),b=getf(eg[i].b);
if(a!=b){
bf[a]=b;
adeg(eg[i].a,eg[i].b,eg[i].l);
adeg(eg[i].b,eg[i].a,eg[i].l);
eg[i].l=inf;eg[i].used=;
j++;
}
}
dep[]=;dfs();
sort(eg+,eg+M+,cmp);
for(i=;i<=N;i++) bf[i]=i,bm[i]=inf;
for(i=;i<=M;i++){
if(eg[i].used) continue;
int a=getf(eg[i].a),b=getf(eg[i].b);
while(a!=b){
if(dep[a]<dep[b]) swap(a,b);
int bb=getf(fa[a][]);
bf[a]=bb,bm[a]=eg[i].l;
a=bb;
}
}
for(i=;i<=M;i++){
if(eg[i].used){
int a=eg[i].a,b=eg[i].b;
if(dep[a]<dep[b]) swap(a,b);
// a=getf(a),b=getf(b);
if(bm[a]<inf) ans[eg[i].ne]=bm[a]-;
else ans[eg[i].ne]=-;
}else{
ans[eg[i].ne]=lca(eg[i].a,eg[i].b)-;
}
}
for(i=;i<=M;i++)
printf("%d ",ans[i]);
return ;
}
cf827D Best Edge Weight (kruskal+倍增lca+并查集)的更多相关文章
- 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集
[题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...
- 【BZOJ-3910】火车 倍增LCA + 并查集
3910: 火车 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 262 Solved: 90[Submit][Status][Discuss] De ...
- Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...
- BZOJ 4144 Dijkstra+Kruskal+倍增LCA
思路: 先把所有的加油站 push进按weight排序的优先队列里 对于每个不是加油站的点 找到到它的点的最短路以及它来源的加油站 如果x和y有边 且x和y加油站的来源不一样 则它可以连边 跑一边Kr ...
- BZOJ 3732 Network Kruskal+倍增LCA
题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 NOIP2013 货车运输.差点儿就是原题...仅仅只是最小边最大改成了最大边最小.. . 首先看到最大值最小第一 ...
- CF827D Best Edge Weight 题解
题意: 给定一个点数为 n,边数为 m,权值不超过 \(10^9\) 的带权连通图,没有自环与重边. 现在要求对于每一条边求出,这条边的边权最大为多少时,它还能出现在所有可能的最小生成树上,如果对于任 ...
- HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 Problem Description Given an undirected connecte ...
- [学习笔记]kruskal重构树 && 并查集重构树
Kruskal 重构树 [您有新的未分配科技点][BZOJ3545&BZOJ3551]克鲁斯卡尔重构树 kruskal是一个性质优秀的算法 加入的边是越来越劣的 科学家们借这个特点尝试搞一点事 ...
- CF1253F Cheap Robot(神奇思路,图论,最短路,最小生成树/Kruskal 重构树/并查集)
神仙题. 先考虑平方级别的暴力怎么做. 明显答案有单调性,先二分 \(c\). 先最短路预处理 \(dis_u\) 表示 \(u\) 到离它最近的充电站的距离(一开始把 \(1\) 到 \(k\) 全 ...
随机推荐
- 安卓自动化测试案例(跑在MonkeyRunner上)
首先文件所在目录: MonkeyRunner所在目录: 运行命令(通过cd 命令 进入Tools目录下): 运行脚本:monkeyrunner.bat ..\honeywell\jsq.py 源文件 ...
- 汇编 LOOP,LOOPD指令
一.LOOP指令 循环控制指令LOOP 格式: LOOP 标号 loopd 功能: 1.ECX=ECX-1 2.(ECX)<>0,则转移至标号处循环执行 3.直至(ECX)=0,继续执行后 ...
- socket、tcp、udp、http 的认识及区别
一.先来一个讲TCP.UDP和HTTP关系的 1.TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层. 在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议. 在传输 ...
- C#_委托与事件
委托: 把方法当作参数进行传递 public delegate void AddDelegate(string name); public class Ad{ //addDelegate就是委托的一个 ...
- Windows 10 中 VMware 要求禁用 Device Guard 问题
今天在打开虚拟机的时候,突然出现下面这个错误.网上给了很多教程,基本上都是禁用 Device Guard 和关闭 Hyper-v,博主按照其方法操作,依旧出现下面错误.后来经过不懈努力,终于找到解决办 ...
- Mysql读写分离方案-Amoeba环境部署记录
Mysql的读写分离可以使用MySQL Proxy,也可以使用Amoeba.Amoeba(变形虫)项目是一个类似MySQL Proxy的分布式数据库中间代理层软件,是由陈思儒开发的一个开源的java项 ...
- kvm虚拟机日常操作命令梳理
KVM虚拟机的管理主要是通过virsh命令对虚拟机进行管理.废话不多说,下面列出kvm日常管理中的命令 1)查看KVM虚拟机配置文件及运行状态 KVM虚拟机默认配置文件位置: /etc/libvirt ...
- java 定时器中任务的启动、停止、再启动
package com.cvicse.ump.timer.service; import java.util.Date; import java.util.Timer; import com.cvic ...
- iOS网络请求安全认证(JWT,RSA)
在网络世界中,安全是一个很重要的问题,以往的HTTP请求已经不能承担这个安全任务,抓包工具一抓,你的所有网络请求全都曝光.当然,你可能会采用加密算法来加密数据,但是这仍然不够. 在移动端和服务器的通信 ...
- 12.17 Daily Scrum
Today's Task Tomorrow's Task 丁辛 实现和菜谱相关的餐厅列表. 实现和菜谱相关的餐厅列表. 邓亚梅 美化搜索框UI. 美 ...