非严格次小生成树

很简单,先做最小生成树

然后枚举没加入的边加入,替换掉这个环内最大的边

最后取\(min\)

严格次小生成树

还是一样的

可以考虑维护一个严格次大值

最大值和枚举的边相同就替换次大值的边

否则替换最大值的边

最后取\(min\)

裸题

Luogu

随你用各种姿势\(AC\)

\(LCT\)常数大,但是好写,开\(O2\)可以过

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(4e5 + 5); IL ll Input(){
RG ll x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
} int ch[2][_], fa[_], rev[_], S[_], mx[_], _mx[_], val[_], anc[_];
int n, m, ff[_], tt[_], w[_], id[_], vis[_];
ll ans = 1e18, mst; # define ls ch[0][x]
# define rs ch[1][x] IL int Son(RG int x){ return ch[1][fa[x]] == x; } IL int Isroot(RG int x){ return ch[0][fa[x]] != x && ch[1][fa[x]] != x; } IL void Update(RG int x){
mx[x] = val[x], _mx[x] = -1;
if(mx[ls] > mx[x]) _mx[x] = mx[x], mx[x] = mx[ls];
else _mx[x] = max(mx[ls], _mx[x]);
if(mx[rs] > mx[x]) _mx[x] = mx[x], mx[x] = mx[rs];
else _mx[x] = max(mx[rs], _mx[x]);
_mx[x] = max(_mx[x], max(_mx[ls], _mx[rs]));
} IL void Reverse(RG int x){
if(!x) return;
rev[x] ^= 1, swap(ls, rs);
} IL void Pushdown(RG int x){
if(!rev[x]) return;
rev[x] = 0, Reverse(ls), Reverse(rs);
} IL void Rotate(RG int x){
RG int y = fa[x], z = fa[y], c = Son(x);
if(!Isroot(y)) ch[Son(y)][z] = x; fa[x] = z;
ch[c][y] = ch[!c][x]; fa[ch[c][y]] = y;
ch[!c][x] = y; fa[y] = x;
Update(y);
} IL void Splay(RG int x){
RG int top = 0; S[++top] = x;
for(RG int y = x; !Isroot(y); y = fa[y]) S[++top] = fa[y];
while(top) Pushdown(S[top--]);
for(RG int y = fa[x]; !Isroot(x); Rotate(x), y = fa[x])
if(!Isroot(y)) Son(x) ^ Son(y) ? Rotate(x) : Rotate(y);
Update(x);
} IL void Access(RG int x){
for(RG int y = 0; x; y = x, x = fa[x]) Splay(x), rs = y, Update(x);
} IL void Makeroot(RG int x){
Access(x), Splay(x), Reverse(x);
} IL int Find(RG int x){
return anc[x] == x ? x : anc[x] = Find(anc[x]);
} IL void Split(RG int x, RG int y){
Makeroot(x), Access(y), Splay(y);
} IL void Link(RG int x, RG int y){
Makeroot(x), fa[x] = y;
} IL int Cmp(RG int x, RG int y){ return w[x] < w[y]; } int main(RG int argc, RG char* argv[]){
n = Input(), m = Input();
for(RG int i = 1; i <= n; ++i) val[i] = -1, anc[i] = i;
for(RG int i = 1; i <= m; ++i)
ff[i] = Input(), tt[i] = Input(), val[n + i] = w[i] = Input(), id[i] = i;
sort(id + 1, id + m + 1, Cmp);
for(RG int i = 1, j = 1; i <= m && j < n; ++i){
RG int fx = Find(ff[id[i]]), fy = Find(tt[id[i]]);
if(fx == fy) continue;
anc[fx] = fy, mst += w[id[i]], ++j, vis[id[i]] = 1;
Link(ff[id[i]], id[i] + n), Link(tt[id[i]], id[i] + n);
}
for(RG int i = 1; i <= m; ++i){
if(vis[i]) continue;
Split(ff[i], tt[i]);
if(mx[tt[i]] != w[i]) ans = min(ans, mst - mx[tt[i]] + w[i]);
else if(_mx[tt[i]] != w[i]) ans = min(ans, mst - _mx[tt[i]] + w[i]);
}
printf("%lld\n", ans);
return 0;
}

严格次小生成树(Bzoj1977:[Beijing2010组队]次小生成树)的更多相关文章

  1. 【次小生成树】bzoj1977 [BeiJing2010组队]次小生成树 Tree

    Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...

  2. [BZOJ1977][BeiJing2010组队]次小生成树

    题解: 首先要证明一个东西 没有重边的图上 次小生成树由任何一颗最小生成树替换一条边 但是我不会证啊啊啊啊啊啊啊 然后就很简单了 枚举每一条边看看能不能变 但有一个特殊情况就是,他和环上的最大值相等, ...

  3. [bzoj1977][BeiJing2010组队]次小生成树 Tree——树上倍增+lca

    Brief Description 求一个无向图的严格次小生成树. Algorithm Design 考察最小生成树的生成过程.对于一个非树边而言,如果我们使用这一条非树边去替换原MST的路径上的最大 ...

  4. bzoj1977 [BeiJing2010组队]次小生成树 Tree

    和倍增法求lca差不多,维护每个点往上跳2^i步能到达的点,以及之间的边的最大值和次大值,先求出最小生成树,对于每个非树边枚举其端点在树上的路径的最大值,如果最大值和非树边权值一样则找次大值,然后维护 ...

  5. bzoj1977 [BeiJing2010组队]次小生成树 Tree——严格次小生成树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1977 因为严格,所以要记录到 LCA 的一个次小值: 很快写好,然后改掉一堆错误后终于过了样 ...

  6. 【BZOJ1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+倍增

    [BZOJ1977][BeiJing2010组队]次小生成树 Tree Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C ...

  7. BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )

    做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...

  8. 1977: [BeiJing2010组队]次小生成树 Tree

    1977: [BeiJing2010组队]次小生成树 Tree https://lydsy.com/JudgeOnline/problem.php?id=1977 题意: 求严格次小生成树,即边权和不 ...

  9. [BeiJing2010组队]次小生成树 Tree

    1977: [BeiJing2010组队]次小生成树 Tree Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 5168  Solved: 1668[S ...

  10. 【刷题】BZOJ 1977 [BeiJing2010组队]次小生成树 Tree

    Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...

随机推荐

  1. 随机手机号和身份证号码(python)

    在使用selenium2 python自动化过程中,用户添加的时候程序设置的手机号和身份证号码是唯一的,这方面python代码可以实现,以下是调试成功,可以实现的. 具体代码如下 身份证需要下载dis ...

  2. LocalMaxima_NOI导刊2009提高(1)

    先打表,发现\(ans=\sum_{i=1}^n\frac{1}{i}\) 对于小数据可以直接打表 数据很大时,精度相对就比较宽松 欧拉-马斯刻若尼常数=调和级数-自然对数 调和级数为:\(\sum_ ...

  3. 发送POST测试请求的若干方法

    最近在工作中需要测试发送带Json格式body值的HTTP POST请求.起初,我在Linux环境下使用curl命令去发送请求,但是,在发送的过程中却遇到了一些问题,经过一段时间的摸索,发现了以下几种 ...

  4. 揽货最短路径解决方案算法 - C# 蚁群优化算法实现

    需求为(自己编的,非实际项目): 某配送中心进行揽货,目标客户数为50个客户,配送中心目前的运力资源如下: 现有车辆5台 单台运力最大行驶距离200千米 单台运力最大载重公斤1吨 问:运力怎样走法才能 ...

  5. [bzoj4551][Tjoi2016&Heoi2016]树-树链剖分

    Brief Description 给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个 结点,可以打多次标记.) ...

  6. hdu4143 A Simple Problem

    A Simple Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) ...

  7. lamp环境部署脚本

    关于lamp环境的安装脚本,直接复制即可使用 注:apache2.2.X 版本和apache2.4.X版本 本人推荐兼容性版本安装 apache2.4.25 + apr1.5.2 + apr-util ...

  8. 手把手教你在Ubuntu上分别安装Nginx、PHP和Mysql

    手把手教你在Ubuntu上分别安装Nginx.PHP和Mysql

  9. handler机制面试

    handler面试必问 解析: Android提供了Handler和Looper来满足线程间的通信. Handler先进先出原则.Looper类用来管理特定线程内对象之间的消息交换(Message E ...

  10. Python实现二分查找

    老生常谈的算法了. #!/usr/bin/python # -*- coding:utf-8 -*- # Filename: demo.py # 用python实现二分查找 def binarySea ...