P4180 [BJWC2010]严格次小生成树
P4180 [BJWC2010]严格次小生成树
题意
求出一个无向联通图的严格次小生成树。严格次小生成树的定义为边权和大于最小生成树的边权和但不存在另一棵生成树的边权和在最小生成树和严格次小生成树之间(不相等)。
思路
先求出一颗最小生成树,发现严格次小生成树一定是其断了一条边并加了一条边且边权和的增加量最小。
那么我们继续在最小生成树上做。对于每一条不是最小生成树上的边,求出其两端两点间在最小生成树上路径上的边的最大值。然鹅,如果用倍增LCA找,发现如果求出来的最大值与该边权值相等,那么得出的答案就是不合法的。所以我们还必须维护一个倍增范围内严格次小边权。
然后找到最小的值输出就行啦!
对于维护严格次小的值,我认为可以先求出最大值,然后比较找出与最大值不等的最大值就是次大值。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#define int long long
using namespace std;
inline int read(){
int w=0,x=0;char c=getchar();
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
return w?-x:x;
}
namespace star
{
const int maxn=1e5+10,maxm=3e5+10,INF=0x3f3f3f3f3f3f3f3f;
int n,m;
struct Edge{
int u,v,dis;
bool is;
inline bool operator <(const Edge &zp)const {return dis<zp.dis;}
}e[maxm];
int ecnt,head[maxn],to[maxn<<1],Fa[maxn],nxt[maxn<<1],v[maxn<<1],ans=INF,sum,fa[maxn][25],mx[maxn][25],pmx[maxn][25],dep[maxn];
inline int find(int x){return Fa[x]==x?x:Fa[x]=find(Fa[x]);}
inline void addedge(int a,int b,int c){
to[++ecnt]=b,nxt[ecnt]=head[a],head[a]=ecnt,v[ecnt]=c;
to[++ecnt]=a,nxt[ecnt]=head[b],head[b]=ecnt,v[ecnt]=c;
}
inline void kruskal(){
for(int i=1;i<=n;i++)Fa[i]=i;
sort(e+1,e+1+m);
int cnt=0;
for(int i=1;i<=m;i++){
int fx=find(e[i].u),fy=find(e[i].v);
if(fx!=fy){
Fa[fx]=fy;
addedge(e[i].u,e[i].v,e[i].dis);
e[i].is=1;
sum+=e[i].dis;
if(++cnt==n-1)break;
}
}
}
void dfs(int x,int f){
fa[x][0]=f;
dep[x]=dep[f]+1;
for(int i=0;i<=20;i++){
fa[x][i+1]=fa[fa[x][i]][i];
mx[x][i+1]=max(mx[x][i],mx[fa[x][i]][i]);
if(mx[x][i+1]!=mx[x][i])pmx[x][i+1]=max(pmx[x][i+1],mx[x][i]);
if(mx[x][i+1]!=mx[fa[x][i]][i])pmx[x][i+1]=max(pmx[x][i+1],mx[fa[x][i]][i]);
if(mx[x][i+1]!=pmx[x][i])pmx[x][i+1]=max(pmx[x][i+1],pmx[x][i]);
if(mx[x][i+1]!=pmx[fa[x][i]][i])pmx[x][i+1]=max(pmx[x][i+1],pmx[fa[x][i]][i]);
}
for(int i=head[x];i;i=nxt[i]){
int u=to[i];
if(u==f)continue;
mx[u][0]=v[i];
dfs(u,x);
}
}
inline void LCA(int x,int y,int &mxx,const int &MX){
if(dep[x]<dep[y])swap(x,y);
for(int i=20;i+1;i--)if(dep[fa[x][i]]>=dep[y]){
if(mx[x][i]!=MX)mxx=max(mxx,mx[x][i]);
else mxx=max(mxx,pmx[x][i]);
x=fa[x][i];
}
if(x==y)return;
for(int i=20;i+1;i--)if(fa[x][i]!=fa[y][i]){
if(mx[x][i]!=MX)mxx=max(mxx,mx[x][i]);
else mxx=max(mxx,pmx[x][i]);
x=fa[x][i];
if(mx[y][i]!=MX)mxx=max(mxx,mx[y][i]);
else mxx=max(mxx,pmx[y][i]);
y=fa[y][i];
}
if(mx[x][0]!=MX)mxx=max(mxx,mx[x][0]);
else mxx=max(mxx,pmx[x][0]);
if(mx[y][0]!=MX)mxx=max(mxx,mx[y][0]);
else mxx=max(mxx,pmx[y][0]);
}
inline void work(){
n=read(),m=read();
for(int i=1;i<=m;i++)e[i].u=read(),e[i].v=read(),e[i].dis=read();
kruskal();
dfs(1,0);
for(int i=1;i<=m;i++)if(!e[i].is){
int x=e[i].u,y=e[i].v,MX=-INF;
LCA(x,y,MX,e[i].dis);
ans=min(ans,sum-MX+e[i].dis);
}
printf("%lld",ans);
}
}
signed main(){
star::work();
return 0;
}
P4180 [BJWC2010]严格次小生成树的更多相关文章
- 【题解】洛谷P4180 [BJWC2010] 严格次小生成树(最小生成树+倍增求LCA)
洛谷P4180:https://www.luogu.org/problemnew/show/P4180 前言 这可以说是本蒟蒻打过最长的代码了 思路 先求出此图中的最小生成树 权值为tot 我们称这棵 ...
- [BJWC2010]严格次小生成树(LCA,最小生成树)
[BJWC2010]严格次小生成树 题目描述 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说,让小C求出一个无向图 ...
- 洛谷 P4180 【模板】严格次小生成树[BJWC2010]【次小生成树】
严格次小生成树模板 算法流程: 先用克鲁斯卡尔求最小生成树,然后给这个最小生成树树剖一下,维护边权转点权,维护最大值和严格次大值. 然后枚举没有被选入最小生成树的边,在最小生成树上查一下这条边的两端点 ...
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- [BJWC2010] 严格次小生成树
[BJWC2010]严格次小生成树算法及模板 所谓次小生成树,即边权之和第二小的生成树,但所谓严格,就是不能和最小的那个相等. 求解严格次小生成树的方法一般有倍增和LCT两种.当然LCT那么高级的我当 ...
- 【洛谷P4180】严格次小生成树
题目大意:给定一个 N 个顶点,M 条边的带权无向图,求该无向图的一个严格次小生成树. 引理:有至少一个严格次小生成树,和最小生成树之间只有一条边的差异. 题解: 通过引理可以想到一个暴力,即:先求出 ...
- 洛谷P4180 [Beijing2010组队]次小生成树Tree
题目描述 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得 ...
- BZOJ1977/LuoguP4180【模板】严格次小生成树[BJWC2010] (次小生成树)
这道题本身思维难度不大,但综合性强,细节多 在其上浪一个早上,你的 最小生成树 树链剖分 线段树 DEBUG能力... 都大幅提升 细节与思路都在代码里面了. 欢迎hack. #include< ...
- [Luogu] 次小生成树
https://www.luogu.org/problemnew/show/P4180#sub 严格次小生成树,即不等于最小生成树中的边权之和最小的生成树 首先求出最小生成树,然后枚举所有不在最小生成 ...
随机推荐
- CentOS:操作系统级监控及常用计数器解析---除CPU以外
I/O I/O 其实是挺复杂的一个逻辑,但我们今天只说在做性能分析的时候,应该如何定位问题. 对性能优化比较有经验的人(或者说见过世面比较多的人)都会知道,当一个系统调到非常精致的程度时,基本上会卡在 ...
- Centos7拓展磁盘(逻辑增加)
目录 第一步 第二步 第三步 以107.4G的Centos操作系统拓展20G磁盘空间,并将此20G磁盘空间分别分配给/home为例. 第一步 首先查看操作系统分区状况和磁盘占用情况.发现磁盘sda空间 ...
- 【NX二次开发】Block UI 枚举
属性: 常规 类型 描述 BlockID String 控件ID Enable Logical 是否可操作 Group Logical ...
- 使用charles抓取https的方法
自己整理的步骤做个记录 1.下载证书,官方地址:http://www.charlesproxy.com/ssl.zip 可直接点击链接下载:http://charlesproxy.com/getssl ...
- 深入理解Spring事务的那点事
Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获 ...
- win10下简单截图
win10 下面可以 win+shift+s 拖动截图,个人感觉是最简单的
- Vue(13)子组件与父组件超详细解析
父组件和子组件 我们经常分不清什么是父组件,什么是子组件.现在来简单总结下:我们将某段代码封装成一个组件,而这个组件又在另一个组件中引入,而引入该封装的组件的文件叫做父组件,被引入的组件叫做子组件.具 ...
- 浅谈最长上升子序列(O(n*logn)算法)
今天GM讲了最长上升子序列的logn*n算法,但没讲思路... 我看了篇博客,发现-- 说的有道理!!! 首先,举例子: a[7]={1,2,4,3,6,7,5}(假设以1开头) 很明显,LIS=5: ...
- UI自动化学习笔记- Selenium一些特殊操作的处理
一.特殊操作处理 1. 下拉选择框操作 1.1 如何操作下拉选择框 实现方式一 思路:先定位到要操作的option元素,然后执行点击操作 driver.find_element_by_css_sele ...
- Vulkan移植GPUImage的安卓Demo展示
演示Android apk下载 需要Android 8以上. 先看效果图,大约一百多种滤镜,有超过一半的滤镜有参数设置,其参数调整界面使用反射自动生成与绑定. 如下每种选择一些进行展示. 视觉效果 图 ...