Codeforces827D. Best Edge Weight
$n \leq 2e5,m \leq 2e5$的有边权图,对每条边问:不改其他边的情况下这条边最多能是多少使得他一定在所有最小生成树上,如果无穷大输出-1.
典型题+耗时题,CF上的绝望时刻。。打VP时前三题花时间太多,导致这题看完题只剩20min,代码还得再敲稳点。
好进入正题,瞎造一棵最小生成树先然后分树上边和树外边回答,树外边$(x,y)$要替代树链$x-y$的某条边,必须比树链上最大的那条边要小1,是一个树链求$Max$,可以st表搞定;树上的边要刚好不被树外边替代,那应该刚好小于能替代它的最小的树外边,需要拿树外边$(x,y)$的权值来对链$x-y$上的边取个$Min$,对应区间取$Min$和离线查询,可以用排序+并查集(反正求最小生成树的时候边已经排序了)。
原来排序+并查集这种操作叫$the \ \ smaller-to-larger \ \ optimization$啊!
//#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
//#include<queue>
//#include<math.h>
//#include<time.h>
//#include<complex>
#include<algorithm>
using namespace std; int n,m;
#define maxn 200011
#define maxm 400011
struct Edge{int from,to,next,v;}ee[maxm],edge[maxn<<]; int first[maxn],le=;
void in(int x,int y,int v) {Edge &e=edge[le]; e.from=x; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;}
void insert(int x,int y,int v) {in(x,y,v); in(y,x,v);} bool cmpee(const Edge &a,const Edge &b) {return a.v<b.v;}
int ufs[maxn];
int find(int x) {return x==ufs[x]?x:(ufs[x]=find(ufs[x]));} int fa[maxn][],dep[maxn],st[maxn][];
void dfs(int x,int f)
{
fa[x][]=f; dep[x]=dep[f]+;
for (int i=first[x];i;i=edge[i].next)
{
Edge &e=edge[i]; if (e.to==f) continue;
st[e.to][]=e.v; dfs(e.to,x);
}
}
int Log[maxn];
void makefa()
{
Log[]=-; for (int i=;i<=n;i++) Log[i]=Log[i>>]+;
for (int j=;j<=;j++)
for (int i=;i<=n;i++)
{
fa[i][j]=fa[fa[i][j-]][j-];
st[i][j]=max(st[i][j-],st[fa[i][j-]][j-]);
}
} int gg;
int glca(int x,int y)
{
gg=;
if (dep[x]<dep[y]) {int t=x;x=y;y=t;}
for (int j=;j>=;j--) if (dep[fa[x][j]]>=dep[y]) gg=max(st[x][j],gg),x=fa[x][j];
if (x==y) return x;
for (int j=;j>=;j--) if (fa[x][j]!=fa[y][j]) gg=max(gg,max(st[x][j],st[y][j])),x=fa[x][j],y=fa[y][j];
gg=max(gg,max(st[x][],st[y][]));
return fa[x][];
} int val[maxn];
void modify(int x,int y,int v)
{
x=find(x);
while (dep[x]>dep[y])
{
val[x]=v;
x=ufs[x]=find(fa[x][]);
}
} bool vis[maxm]; int ans[maxm];
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=m;i++) scanf("%d%d%d",&ee[i].from,&ee[i].to,&ee[i].v),ee[i].next=i;
sort(ee+,ee++m,cmpee); for (int i=;i<=n;i++) ufs[i]=i;
for (int i=,j=;i<=m && j<n;i++)
{
int x=find(ee[i].from),y=find(ee[i].to);
if (x==y) continue;
ufs[x]=y; insert(ee[i].from,ee[i].to,ee[i].v); vis[i]=; j++;
}
dfs(,); makefa(); for (int i=;i<=n;i++) ufs[i]=i;
for (int i=;i<=n;i++) val[i]=0x3f3f3f3f;
for (int i=;i<=m;i++) if (!vis[i])
{
int x=ee[i].from,y=ee[i].to,l=glca(x,y);
ans[ee[i].next]=gg-;
modify(x,l,ee[i].v); modify(y,l,ee[i].v);
}
for (int i=;i<=m;i++) if (vis[i])
{
int x=ee[i].from,y=ee[i].to;
if (dep[x]<dep[y]) x=y;
ans[ee[i].next]=val[x]-;
}
for (int i=;i<=m;i++) printf("%d ",ans[i]==0x3f3f3f3f-?-:ans[i]);
return ;
}
Codeforces827D. Best Edge Weight的更多相关文章
- 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集
[题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...
- CF#633 D. Edge Weight Assignment
D. Edge Weight Assignment 题意 给出一个n个节点的树,现在要为边赋权值,使得任意两个叶子节点之间的路径权值异或和为0,问最多,最少有多少个不同的权值. 题解 最大值: 两个叶 ...
- CF 633 div1 1338 B. Edge Weight Assignment 构造
LINK:Edge Weight Assignment 这场当时没打 看到这个B题吓到我了 还好当时没打. 想了20min才知道怎么做 而且还不能证明. 首先考虑求最小. 可以发现 如果任意两个叶子节 ...
- 【Codeforces827D/CF827D】Best Edge Weight(最小生成树性质+倍增/树链剖分+线段树)
题目 Codeforces827D 分析 倍增神题--(感谢T*C神犇给我讲qwq) 这道题需要考虑最小生成树的性质.首先随便求出一棵最小生成树,把树边和非树边分开处理. 首先,对于非树边\((u,v ...
- Codeforces 828F Best Edge Weight - 随机堆 - 树差分 - Kruskal - 倍增算法
You are given a connected weighted graph with n vertices and m edges. The graph doesn't contain loop ...
- cf827D Best Edge Weight (kruskal+倍增lca+并查集)
先用kruskal处理出一个最小生成树 对于非树边,倍增找出两端点间的最大边权-1就是答案 对于树边,如果它能被替代,就要有一条非树边,两端点在树上的路径覆盖了这条树边,而且边权不大于这条树边 这里可 ...
- 浴谷夏令营例题Codeforces827DBest Edge Weight(三个愿望,一次满足~(大雾
这题在浴谷夏令营wyx在讲的最小生成树的时候提到过,但并没有细讲怎么写... 这题可以用三种写法写,虽然只有两种能过...(倍增/倍增+并查集/树链剖分 先跑出最小生成树,分类讨论,在MST上的边,考 ...
- CF827D Best Edge Weight 题解
题意: 给定一个点数为 n,边数为 m,权值不超过 \(10^9\) 的带权连通图,没有自环与重边. 现在要求对于每一条边求出,这条边的边权最大为多少时,它还能出现在所有可能的最小生成树上,如果对于任 ...
- CF827D Best Edge Weight[最小生成树+树剖/LCT/(可并堆/set启发式合并+倍增)]
题意:一张图求每条边边权最多改成多少可以让所有MST都包含这条边. 这题还是要考察Kruskal的贪心过程. 先跑一棵MST出来.然后考虑每条边. 如果他是非树边,要让他Kruskal的时候被选入,必 ...
随机推荐
- 详解 Handler 消息处理机制(附自整理超全 Q&A)
Android 为什么要用消息处理机制 如果有多个线程更新 UI,并且没有加锁处理,会导致界面更新的错乱,而如果每个更新操作都进行加锁处理,那么必然会造成性能的下降.所以在 Android 开发中,为 ...
- IP地址 子网掩码 默认网关和DNS服务器的关系
在过去,男人是需要能够上房揭瓦的,是要能够修水管的.现在的男人是需要会装系统的,会设置路由器的.世界变化太快! 废话不多说,本文来讨论一下电脑上最为常见的几个网络参数:IP地址.子网掩码.默认网关和D ...
- 10个顶级的CSS3代码生成器
新出来的在线工具和web应用允许开发人员快速创建网站,而无需手动一行一行地编写代码.当前,不断有新的框架和代码库涌现在前端开发这个领域里. 但是,这也让许多开发人员忘记了代码生成器以及它们在构建网站时 ...
- qt 设置阴影 不显示黑色边框
this->setAttribute(Qt::WA_TranslucentBackground);
- COGS 2098. Asm.Def的病毒
★☆ 输入文件:asm_virus.in 输出文件:asm_virus.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] “这就是我们最新研制的,世界上第一种可持 ...
- PHP CLI应用的调试原理
我们在Eclipse里选中一个PHP文件,右键选择Debug As->PHP CLI Application. 所谓CLI应用,是指这种脚本文件不需要任何Web服务器即可运行,当然, PHP运行 ...
- Android(java)学习笔记175:Android进程间通讯(IPC)之AIDL
一.IPC inter process communication 进程间通讯 二.AIDL android interface defination language 安卓接口定义语言 满 ...
- 在Eclipse中通过JDBC连接MySQL步骤,非常详细!
通过JDBC连接MySQL基本步骤代码讲解步骤可能遇到的Bug基本步骤JDBC访问MySQL 1.加载JDBC驱动器—>哪个project需要,就添加到该project的jdbc文件夹下,我的j ...
- python程序的编辑和运行、变量
第一个python程序 python是解释型弱类型高级语言 常见的python解释器CPython.IPython.pypy.JPython.IronPython 方法一.python程序可以写在命令 ...
- [ERROR ] Error parsing configuration file: /etc/salt/minion - conf should be a document, not <type 'str'>.
错误信息 [ERROR ] Error parsing configuration file: /etc/salt/minion - conf should be a document, not &l ...