题目大意:找出两点间一条路径,使路径上最大的边最小,含加边操作
改悔!
比赛的时候看到这道题(读题读了很久),就想到了看到过的WC2006水管局长那道题,这道题数据还要水一些。
做法就是维护MST,用LCT加边,加边的时候找一下两个点间最长的一条边,如果比要加的边长,就删掉这条边然后加边,否则不加边
然而我用了一个想当然的写法,导致样例都出不了
LCT只能维护点权,但MST需要维护的是边权,就需要把边权转化为点权
考虑到以前树剖的写法,我把树上一条边的权值加到深的点上,这样除了根节点,每个点的权值表示它到其父节点的边权
然而LCT如果也这么搞,那就GG了
原因是LCT中link、cut都需要换根操作,换根之后,部分节点的父子关系被调换了,而我们也无法将经过如上处理的点权下放,所以LCT维护边权肯定不能这么搞的(除非你不用link和cut)
那么就只能用笨一点的方法了,我们把每条边看作一个点,该点与原边的两端点连边,它的权值就是边的权值,这样原有结构就不会被lct操作破坏了
代码:
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=200005,M=N<<2;
//inline int _R(){
// int d=0;bool b=1;char t=getchar();
// while(t<'0'||t>'9'){if(t=='-')b=0;t=getchar();}
// for(;t>='0'&&t<='9';t=getchar())d=(d<<3)+(d<<1)+t-'0';
// return b?d:-d;
<