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的时候被选入,必 ...
随机推荐
- LN : leetcode 215 Kth Largest Element in an Array
lc 215 Kth Largest Element in an Array 215 Kth Largest Element in an Array Find the kth largest elem ...
- [BZOJ2761][JLOI2011]不重复数字 暴力
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2761 直接暴力. #include<cstdio> #include<c ...
- [BZOJ1053][SDOI2005]反素数ant 数学
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1053 假设这个最大的反素数为$x$,那么$1<p<x$中数的因子数都没有$x$ ...
- Ant题解
Description: 一根长度为L厘米的木棒上有N只蚂蚁,每只蚂蚁要么向左走,要么向右走,速度为1厘米/秒.当两只蚂蚁相撞时,他们会同时掉头(掉头时间不计)给出每只蚂蚁距离木棒左端的距离,问多少秒 ...
- Android学习笔记(十七) BroadcastReceiver
1.接收广播 创建一个类,继承BroadcastReceiver,复写其中的onReceive()方法 在AndroidManifest.xml文件中注册该BroadcastReceiver 设置完成 ...
- android开发工具eclipse的安装与配置
l开发主要应用Eclipse 3.7版本. l辅助工具为jdk.Androidsdk Android环境搭建 –1.1.JDK安装 –1.2.Eclipse安装 –1.3.Android SDK安 ...
- jdbc获取数据具体过程
下面是个最简单的使用jdbc取得数据的应用.在例子之后我将分成4步,分别是①取得连接,②创建PreparedStatement,③设置参数,④执行查询,来分步分析这个过程.除了设置参数那一步之外,其他 ...
- COGS 495. 窗口
★☆ 输入文件:window.in 输出文件:window.out 简单对比时间限制:2 s 内存限制:256 MB [问题描述] 给你一个长度为N的数组,一个长为K的滑动的窗体从最左 ...
- 【Conclusion】MySQL的安装和使用
MySQL使用 因为数据库实验用到了MySQL,这里对现在已经涉及到的MySQL部分操作做一个简单的小结. 1.安装MySQL 上MySQL的官网下载对应自己OS平台的MySQL安装文件,有在线安装和 ...
- Two-Phase Commit (2PC)
两阶段提交模式像极了比赛发令:“预备,开始!”