明天就省选了,我咋啥也不会
最破防的一集
一道LCT调了一下午没调出来
最后发现是 min
和 max
取反了
改完之后发现自己的访问有问题,如果有 0
边权我就会直接返回LLONG_MAX
啊哈哈,我调了一下午,发了7个帖子
然后校内OJ过了,POJ因为只有C++98所以 CE 了
哈哈哈
写个简要题解吧
-
这道题与一般的
LCT
似乎有一点不同给的不是点权,那怎么办呢
错误思考示范
诶树剖的时候好像也有这个问题,是不是可以参考树剖
用儿子节点记录其到其父亲的边权,然后云云
但是这样有个问题,就是说
LCT
使用splay
维护的,splay
是会破坏原本的父子关系的那么这个做法宣告破产了wwwww
根据
FalshHu
的讲解,我们可以得知有两种解法-
把边置于
LCT
外,然后在LCT
节点中维护父边和重子边的编号,需要更新信息时从外部获取但是这种方法有一个问题:需要在
access
操作,Link
操作,Cut
操作都进行修改,很麻烦 -
建立额外的节点
我们可以建立额外的表示边的节点,然后把表示点的节点的权值都设为\(0\)
这样我们就可以把原本的边权转化为点权来让
LCT
去维护此时普通的
Link
和Cut
都存在一些问题Link
和Cut
操作只能添加/删除一条边,而不能删除代表边权的边解决方法也很简单,直接
Link
/Cut
两次即可-
核心代码
link(a[i].x,a[i].id); link(a[i].id,a[i].y);
-
我们通常选择建立代表边的节点,也就是第二种方法
在本题中建立边的方式如下
for(int i=1;i<n;++i){ FastI>>x>>y>>val[i+n]; link(x,i+n); link(y,i+n); }
这里的求
max
后取反如何维护呢?我们发现只要取min
即可,这样取相反数后的结果就是max
那么这道题就非常容易的做出来了
-