$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的更多相关文章

  1. 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集

    [题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...

  2. CF#633 D. Edge Weight Assignment

    D. Edge Weight Assignment 题意 给出一个n个节点的树,现在要为边赋权值,使得任意两个叶子节点之间的路径权值异或和为0,问最多,最少有多少个不同的权值. 题解 最大值: 两个叶 ...

  3. CF 633 div1 1338 B. Edge Weight Assignment 构造

    LINK:Edge Weight Assignment 这场当时没打 看到这个B题吓到我了 还好当时没打. 想了20min才知道怎么做 而且还不能证明. 首先考虑求最小. 可以发现 如果任意两个叶子节 ...

  4. 【Codeforces827D/CF827D】Best Edge Weight(最小生成树性质+倍增/树链剖分+线段树)

    题目 Codeforces827D 分析 倍增神题--(感谢T*C神犇给我讲qwq) 这道题需要考虑最小生成树的性质.首先随便求出一棵最小生成树,把树边和非树边分开处理. 首先,对于非树边\((u,v ...

  5. 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 ...

  6. cf827D Best Edge Weight (kruskal+倍增lca+并查集)

    先用kruskal处理出一个最小生成树 对于非树边,倍增找出两端点间的最大边权-1就是答案 对于树边,如果它能被替代,就要有一条非树边,两端点在树上的路径覆盖了这条树边,而且边权不大于这条树边 这里可 ...

  7. 浴谷夏令营例题Codeforces827DBest Edge Weight(三个愿望,一次满足~(大雾

    这题在浴谷夏令营wyx在讲的最小生成树的时候提到过,但并没有细讲怎么写... 这题可以用三种写法写,虽然只有两种能过...(倍增/倍增+并查集/树链剖分 先跑出最小生成树,分类讨论,在MST上的边,考 ...

  8. CF827D Best Edge Weight 题解

    题意: 给定一个点数为 n,边数为 m,权值不超过 \(10^9\) 的带权连通图,没有自环与重边. 现在要求对于每一条边求出,这条边的边权最大为多少时,它还能出现在所有可能的最小生成树上,如果对于任 ...

  9. CF827D Best Edge Weight[最小生成树+树剖/LCT/(可并堆/set启发式合并+倍增)]

    题意:一张图求每条边边权最多改成多少可以让所有MST都包含这条边. 这题还是要考察Kruskal的贪心过程. 先跑一棵MST出来.然后考虑每条边. 如果他是非树边,要让他Kruskal的时候被选入,必 ...

随机推荐

  1. AJPFX实例集合嵌套之ArrayList嵌套ArrayList

    案例:import java.util.ArrayList;import java.util.Iterator;import com.heima.bean.Person;public class De ...

  2. MySQL读写分离实现

    数据库写入效率要低于读取效率,一般系统中数据读取频率高于写入频率,单个数据库实例在写入的时候会影响读取性能,这是做读写分离的原因.实现方式主要基于mysql的主从复制,通过路由的方式使应用对数据库的写 ...

  3. Android性能分析工具Profile GPU rendering详细介绍

    如何在一个应用中追踪和定位性能问题,甚至在没有它的源代码的情况下?? “Profile GPU rendering”(GPU渲染分析),一款Android4.1所引入的工具.你可以在“设置”应用的“开 ...

  4. 8.3.3 快速系统调用 —— XP SP3上SystemCallStub的奇怪问题

    依书上的例子,ReadFile()函数会调用ntdll!NtReadFile(),后者将服务号放到eax之中,然后调用SharedUserData!SystemCallStub(),由此函数执行sys ...

  5. spring 常见的注解

    spring中的注解都必须在配置文件中进行如下的配置: <context:component-scan base-package="com.shanjin.oxm.service.im ...

  6. SAS Fuctions

    1. monotonic(), 单调递增函数.返回一列变量的序列等,类似于_N_ . 2. index v indexw: INDEX Function Searches a character ex ...

  7. MVVM没你想象的那么的好

    我写过很多有关于让View Controller 更易于理解的文章,其中一种比较常见的模式就是Model-View-ViewModel(MVVM). 我认为MVVM 是一种非常容易让人混淆的 anti ...

  8. 【2019-5-26】python:字典、常用字符串处理方法及文件操作

    一.数据类型:字典 1.字典: 1.1定义字典:dict={'key':'value'} 1.2字典与列表相比,字典取值快,可直接找到key 1.3字典是无序的,不能根据顺序取值 1.4多个元素用逗号 ...

  9. 使用github中py12306抢票系得

    首先需要安装最新的python:安装步骤见:https://www.cnblogs.com/weven/p/7252917.html 其次下载python源码: 链接:https://pan.baid ...

  10. 【练习】reserving.kr 之imageprc write up

    补充:c++ builder 与 windows  API经典范例 #include <vcl.h> #pragma hdrstop #include "Unit1.h" ...