非严格次小生成树

很简单,先做最小生成树

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

最后取\(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. 【Tools】ubuntu16.04升级Python2.7到3.5

    最近开始学Python,但我发现我ubuntu16.04上默认的Python是2.7,并不是3,x 于是准备Python升级,记录安装过程给初学者参考一下. 1.先取得管理员权限, 个人习惯先取得管理 ...

  2. RTLabel 的简单使用

    RTLabel 基于富文本的格式,适用于iOS,类似HTML的标记. RTLabel 基于UILabel类的拓展,能够支持Html标记的富文本显示,它是基于Core Text,因此也支持Core Te ...

  3. 在OS X系统中php访问sftp时需要ssh2扩展的安装

    php -v brew install homebrew/php/php55-ssh2 [实现方式] <?php $connection = ssh2_connect('192.168.0.14 ...

  4. 低版本IE内核浏览器兼容placeholder属性解决办法

    最简便的一个方法,通过js实现. <input type="text" name="username" id="username" v ...

  5. dedecms织梦判断当前页面是首页、栏目页还是文章页

    根据全局变量$GLOBALS['_sys_globals']['curfile']的值来判断. 首页parview:列表页listview:文章页archives 应用示例: {dede:php}if ...

  6. python进阶学习笔记(二)

    1.模块和包的概念 python的解决方案是把同名的模块放到不同的包中 1.1,导入模块 要使用一个模块,我们必须首先导入该模块.Python使用import语句导入一个模块.例如,导入系统自带的模块 ...

  7. hadoopmaster主机上传文件出错: put: File /a.txt._COPYING_ could only be replicated to 0 nodes instead of minReplication (=1). There are 3 datanode(s) running and 3 node(s) are excluded in this operation.

    刚开始装好hadoop的时候,namenode机上传文件没有错误,今天打开时突然不能上传文件,报错 put: File /a.txt._COPYING_ could only be replicate ...

  8. ADO.NET通用类库

    using System.Data; using System.Data.SqlClient; namespace DataService { public class SQLHelper { pub ...

  9. vim学习、各类插件配置与安装

    vim学习.各类插件配置与安装 vim 插件 配置 1. vim学习 vim基础学习:根据网上流行基础文章<简明Vim练级攻略>,进阶书籍<vim实用技巧>.注:进阶书籍可以在 ...

  10. PAT1119. Pre- and Post-order Traversals

    思路:中序遍历–根结点,左子树,右子树:后序遍历–左子树,右子树,根结点. 那么在找到根结点之后就可以开始划分左右子树了.左子树的先序第一个节点是根,左子树的后序最后一个节点是根. 例如 1 2 3 ...