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的时候被选入,必 ...
随机推荐
- re正则表达式公式讲解6
标识符 re.I (re.IGNORECASE) 忽略大小写 import re s = "Max@123uyt146" print(re.search("m" ...
- 探究SQL添加非聚集索引,性能提高几十倍之谜
上周,技术支持反映:客户的一个查询操作需要耗时6.1min左右,在跟进代码后,简化了数据库的查询后仍然收效甚微.后来,技术总监分析了sql后,给其中的一个表添加的一个非聚集索引(三个字段)后,同样的查 ...
- Python调用Java代码部署及初步使用
Python调用Java代码部署: jpype下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#jpype 下载的时候需要使用Chrome浏览器进行下载 ...
- 客户端配置snmpd
[root@ localhost]#yum install net-snmp (3)安装后打开默认的/etc/snmp/snmpd.conf文件,更改如下配置: 1) 查找以下代码: # sec.na ...
- laravel学习笔记(二)
路由 HTTP方法:支持http1.1中所有类型传参方式,get,post,put,delete,options,patch Route::get($url,$callback); 路由参数: Rou ...
- UVA 11971 Polygon 多边形(连续概率)
题意: 一根长度为n的木条,随机选k个位置将其切成k+1段,问这k+1段能组成k+1条边的多边形的概率? 思路: 数学题.要求的是概率,明显与n无关. 将木条围成一个圆后再开切k+1刀,得到k+1段. ...
- 如何在Ubuntu里安装Helm
Helm是什么?在战网上玩过暗黑破坏神2代的程序员们应该还记得,Helm是国度的意思. 而在计算机领域,Helm是什么? Helm是Kubernetes的一个包管理工具,有点像nodejs的npm,U ...
- 主席树-指针实现-找第k小数
主席树,其实就是N颗线段树 只是他们公用了一部分节点(๑•̀ㅂ•́)و✧ 我大部分的代码是从一位大佬的那里看到的 我这个垃圾程序连Poj2104上的数据都过不了TLE so希望神犇能给我看看, 顺便给 ...
- vue 数组对接字符串 传值时候,join(',') 一下 watch
vue 数组对接字符串 传值时候,join(',') 一下 watch watch: { 'tFill.otherDescArr': function (newVal, oldVal) { this. ...
- mfc消息
ON_COMMAND是菜单和工具栏项处理消息的宏 ON_MESSAGE是处理自定义消息的宏 ON_NOTIFY 是控件向其父窗口发送消息处理的宏 对这几个消息的理解要先了解一下Window消息的背景. ...