[BJOI 2010]次小生成树Tree
Description
小 C 最近学了很多最小生成树的算法,Prim 算法、Kurskal 算法、消圈算法等等。 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了。小 P 说,让小 C 求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说: 如果最小生成树选择的边集是 EM,严格次小生成树选择的边集是 ES,那么需要满足:(value(e) 表示边 e的权值)
这下小 C 蒙了,他找到了你,希望你帮他解决这个问题。
Input
第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z。
Output
包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)
Sample Input
1 2 1
1 3 2
2 4 3
3 5 4
3 4 3
4 5 6
Sample Output
Hint
数据中无向图无自环; 50% 的数据N≤2 000 M≤3 000; 80% 的数据N≤50 000 M≤100 000; 100% 的数据N≤100 000 M≤300 000 ,边权值非负且不超过 10^9 。
题解
次小生成树模板。简便地直接用$LCA$做。唯一注意的是由于它要求严格的次小生成树,所以我们$LCA$时还要记得保存次大值。(防止边权相等)
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const LL N=; LL n,m,op,x,y,p,q,d=2e15;
struct aa
{
LL u,v,c;
}lin[N*+];
bool comp(aa a,aa b); LL mst,cnt;
struct bb
{
LL to,next,cost;
}edge[N*+];
LL path[N+],top;
bool vis[N*+];
void Add(LL u,LL v,LL c); LL set[N+];
LL Find(LL x); LL f[N+][],maxn[N+][],sub[N+][];
LL dep[N+];
void Dfs(LL x,LL depth);
void Lca(LL x,LL y,LL c); int main()
{
scanf("%lld%lld",&n,&m);
op=log2(n);
for (LL i=;i<=m;i++) scanf("%lld%lld%lld",&lin[i].u,&lin[i].v,&lin[i].c);
sort(lin+,lin+m+,comp);
for (LL i=;i<=m;i++)
{
p=Find(lin[i].u);
q=Find(lin[i].v);
if (p!=q)
{
set[p]=q;
cnt++;
mst+=lin[i].c;
vis[i]=;
Add(lin[i].u,lin[i].v,lin[i].c);
Add(lin[i].v,lin[i].u,lin[i].c);
if (cnt==n-) break;
}
}
if (cnt<n-)
{
printf("No MST!\n");
return ;
}
Dfs(,);
for (LL t=;t<=op;t++)
for (LL i=;i<=n;i++)
if (f[i][t-])
{
f[i][t]=f[f[i][t-]][t-];
x=maxn[i][t-];y=sub[i][t-];
p=maxn[f[i][t-]][t-];q=sub[f[i][t-]][t-];
if (x==p){maxn[i][t]=x;sub[i][t]=max(y,q);}
else if (x>p){maxn[i][t]=x;sub[i][t]=max(p,y);}
else if (x<p){maxn[i][t]=p;sub[i][t]=max(x,q);}
}
for (LL i=;i<=m;i++) if (!vis[i]) Lca(lin[i].u,lin[i].v,lin[i].c);
if (d==2e15) printf("No SST!");
else printf("%lld\n",mst+d);
return ;
} bool comp(aa a,aa b){return a.c<b.c;}
void Add(LL u,LL v,LL c)
{
edge[++top].to=v;
edge[top].next=path[u];
edge[top].cost=c;
path[u]=top;
}
LL Find(LL x){return set[x] ? set[x]=Find(set[x]):x;}
void Dfs(LL x,LL depth)
{
dep[x]=depth;
for (LL i=path[x];i;i=edge[i].next) if (!dep[edge[i].to])
{
f[edge[i].to][]=x;
maxn[edge[i].to][]=edge[i].cost;
Dfs(edge[i].to,depth+);
}
}
void Lca(LL x,LL y,LL c)
{
LL m1=,m2=;
if (dep[x]<dep[y]) swap(x,y);
for (LL i=op;i>=;i--) if (dep[x]-(<<i)>=dep[y])
{
if (sub[x][i]>m1){m2=m1;m1=sub[x][i];}
else if (sub[x][i]>m2&&sub[x][i]!=m1) m2=sub[x][i];
if (maxn[x][i]>m1){m2=m1;m1=maxn[x][i];}
else if (maxn[x][i]>m2&&maxn[x][i]!=m1) m2=maxn[x][i];
x=f[x][i];
}
if (x!=y)
{
for (LL i=op;i>=;i--) if (f[x][i]!=f[y][i])
{
if (sub[x][i]>m1){m2=m1;m1=sub[x][i];}
else if (sub[x][i]>m2&&sub[x][i]!=m1) m2=sub[x][i];
if (maxn[x][i]>m1){m2=m1;m1=maxn[x][i];}
else if (maxn[x][i]>m2&&maxn[x][i]!=m1) m2=maxn[x][i];
if (sub[y][i]>m1){m2=m1;m1=sub[y][i];}
else if (sub[y][i]>m2&&sub[y][i]!=m1) m2=sub[y][i];
if (maxn[y][i]>m1){m2=m1;m1=maxn[y][i];}
else if (maxn[y][i]>m2&&maxn[y][i]!=m1) m2=maxn[y][i];
x=f[x][i];
y=f[y][i];
}
if (sub[x][]>m1){m2=m1;m1=sub[x][];}
else if (sub[x][]>m2&&sub[x][]!=m1) m2=sub[x][];
if (maxn[x][]>m1){m2=m1;m1=maxn[x][];}
else if (maxn[x][]>m2&&maxn[x][]!=m1) m2=maxn[x][];
if (sub[y][]>m1){m2=m1;m1=sub[y][];}
else if (sub[y][]>m2&&sub[y][]!=m1) m2=sub[y][];
if (maxn[y][]>m1){m2=m1;m1=maxn[y][];}
else if (maxn[y][]>m2&&maxn[y][]!=m1) m2=maxn[y][];
}
if (m1==) return;
if (c==m1)
{
if (m2==) return;
d=min(d,c-m2);
}
else d=min(d,c-m1);
}
[BJOI 2010]次小生成树Tree的更多相关文章
- BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...
- 1977: [BeiJing2010组队]次小生成树 Tree
1977: [BeiJing2010组队]次小生成树 Tree https://lydsy.com/JudgeOnline/problem.php?id=1977 题意: 求严格次小生成树,即边权和不 ...
- 【BZOJ1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+倍增
[BZOJ1977][BeiJing2010组队]次小生成树 Tree Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C ...
- [BeiJing2010组队]次小生成树 Tree
1977: [BeiJing2010组队]次小生成树 Tree Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 5168 Solved: 1668[S ...
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- [BeiJing2010组队][BZOJ 1977]次小生成树 Tree
话说这个[BeiJing2010组队]是个什喵玩意? 这是一道严格次小生成树,而次小生成树的做法是层出不穷的 MATO IS NO.1 的博客里对两种算法都有很好的解释,值得拥有: (果然除我以外, ...
- 【次小生成树】bzoj1977 [BeiJing2010组队]次小生成树 Tree
Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...
- (luogu4180) [Beijing2010组队]次小生成树Tree
严格次小生成树 首先看看如果不严格我们怎么办. 非严格次小生成树怎么做 由此,我们发现一个结论,求非严格次小生成树,只需要先用kruskal算法求得最小生成树,然后暴力枚举非树边,替换路径最大边即可. ...
- BZOJ 1977[BeiJing2010组队]次小生成树 Tree - 生成树
描述: 就是求一个次小生成树的边权和 传送门 题解 我们先构造一个最小生成树, 把树上的边记录下来. 然后再枚举每条非树边(u, v, val),在树上找出u 到v 路径上的最小边$g_0$ 和 严格 ...
随机推荐
- web服务器学习2---httpd-2.4.29虚拟目录及访问控制
一 创建虚拟目录 环境准备: 系统:CentOS 7.4 软件:httpd-2.4.29 1.编辑主配置文件,添加命令运行子配置文件 vi /usr/local/httpd/conf/httpd.co ...
- 巨人大哥谈Java中的Synchronized关键字用法
巨人大哥谈Java中的Synchronized关键字用法 认识synchronized 对于写多线程程序的人来说,经常碰到的就是并发问题,对于容易出现并发问题的地方价格synchronized基本上就 ...
- 软件工程网络15团队作业1——团队组队&展示
Deadline: 2018-3-25 10:00PM,以提交至班级博客时间为准. 申请开通团队博客,并将团队博客地址发表在本次随笔的评论中 团队展示 根据5-6人的组队要求,每个队伍创建团队博客并发 ...
- beta冲刺 用户使用调查报告
测评结果 一.使用体验 数据加载响应很快,页面切换丝滑流畅. UI有点偏暗,有些字被覆盖了. 页面布局过于居中,两侧空白范围较大. 总体功能完善. 二.登录.注册.忘记密码界面 管理员登录按钮太靠下, ...
- Software Engineering-HW8 个人总结
Software Engineering-HW8 个人总结 2017282110264 李世钰 一.请参考第一次作业,当初你对课程的承诺和期望都兑现了吗? 大致实现了.经过了最后的团队项目,基本了解一 ...
- HASH方法课下补分博客
课堂要求:利用除留余数法为下列关键字集合的存储设计hash函数,并画出分别用开放寻址法和拉链法解决冲突得到的空间存储状态(散列因子取0.75)关键字集合:85,75,57,60,65,(你的8位学号相 ...
- 第201621123043 《Java程序设计》第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 系统还在创建中..... 为了让你 ...
- 200行Python代码实现2048
200行Python代码实现2048 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面 ...
- mysql基础篇 - 其他基本操作
基础篇 - 其他基本操作 其他基本操作 一.实验简介 本节实验中我们将学习并实践数据库的其他基本操作:索引.视图,导入和导出,备份和恢复等. 这些概念对于数据库管理员而言都非常重要,请 ...
- Storm概念讲解和工作原理介绍
Strom的结构 Storm与传统关系型数据库 传统关系型数据库是先存后计算,而storm则是先算后存,甚至不存 传统关系型数据库很难部署实时计算,只能部署定时任务统计分析窗口数据 ...