题目描述

小C最近学了很多最小生成树的算法,Prim算法、Kurskal算法、消圈算法等等。正当小C洋洋得意之时,小P又来泼小C冷水了。小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说:如果最小生成树选择的边集是EM,严格次小生成树选择的边集是ES,那么需要满足:(value(e)表示边e的权值) \sum_{e \in E_M}value(e)<\sum_{e \in E_S}value(e)∑e∈EM​​value(e)<∑e∈ES​​value(e)

这下小 C 蒙了,他找到了你,希望你帮他解决这个问题。

输入输出格式

输入格式:

第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z。

输出格式:

包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)

输入输出样例

输入样例#1: 复制

5 6
1 2 1
1 3 2
2 4 3
3 5 4
3 4 3
4 5 6
输出样例#1: 复制

11

说明

数据中无向图无自环; 50% 的数据N≤2 000 M≤3 000; 80% 的数据N≤50 000 M≤100 000; 100% 的数据N≤100 000 M≤300 000 ,边权值非负且不超过 10^9 。

题解

话说这个还没有经典到当模板吧qwq

先做一个最小生成树,图被分成树边和非树边。

在这个树上随便找个点当根,预处理好倍增的东西(包括往上$2^j$步的祖先编号,往祖先走的这条路上最长的边,这条路上第二长的边

然后把每条非树边跑一遍,设两点为$u,v$。

可以想到,从$u$到$v$的这条树上路径中找一条最大但小于这条非树边的边替换,这样的结果是严格次小生成树的一个备选结果。

所以就一边求lca一边跟那一段的最长边和第二长边对比啊什么的。

//记录第二长边主要是防止最长边和这条非树边一样长

作为紫题非常好写,非常不容易错。(毕竟只是倍增lca和Kruscal揉到一起的一个东西,元件都不难写qwq

但确实很长就是了qwq

 /*
qwerta
P4180 【模板】严格次小生成树[BJWC2010] Accepted
100
代码 C++,2.72KB
提交时间 2018-10-31 19:50:25
耗时/内存 1812ms, 35376KB
*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
inline int read()
{
char ch=getchar();
int x=;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x;
}
const int MAXN=1e5+,MAXM=3e5+;
struct emm{
int x,y,l,tag;
}b[MAXM];//用来存原图,tag表示是否为树边
bool cmp(emm qaq,emm qwq){
return qaq.l<qwq.l;
}//用来最小生成树
int fa[MAXN];
int fifa(int x)
{
if(fa[x]==x)return x;
return fa[x]=fifa(fa[x]);
}
struct ahh{
int e,f,l;
}a[*MAXN];//用来存树
int h[MAXN];
int tot=;
void con(int x,int y,int l)//连树边
{
a[++tot].f=h[x];
h[x]=tot;
a[tot].e=y;
a[tot].l=l;
a[++tot].f=h[y];
h[y]=tot;
a[tot].e=x;
a[tot].l=l;
return;
}
int w[MAXN],d[MAXN];//w把边权记在深度较深的点上,d为深度
void dfs(int x)//dfs建树
{
for(int i=h[x];i;i=a[i].f)
if(!d[a[i].e])
{
fa[a[i].e]=x;
d[a[i].e]=d[x]+;
w[a[i].e]=a[i].l;
dfs(a[i].e);
}
return;
}
int f[MAXN][];//往上2^j步的祖先
int mac[MAXN][];//往上2^j步途中最长的边长
int macc[MAXN][];//往上2^j步途中严格第二长的边长
int zz[];//辅助数组
bool cmpp(int qaq,int qwq){
return qaq>qwq;
}//用来给zz排序
int main()
{
//freopen("a.in","r",stdin);
int n=read(),m=read();
for(int i=;i<=m;++i)
{
b[i].x=read(),b[i].y=read(),b[i].l=read();
}
//做个最小生成树↓
sort(b+,b+m+,cmp);
for(int i=;i<=n;++i)
fa[i]=i;
int k=n-,j=;
long long sum=;
while(k)
{
j++;
int u=fifa(b[j].x),v=fifa(b[j].y);
if(u!=v)
{
fa[u]=v;
//cout<<b[j].x<<" "<<b[j].y<<" "<<b[j].l<<endl;
b[j].tag=;
sum+=b[j].l;//记下树边权值和
con(b[j].x,b[j].y,b[j].l);//把两点连起来
k--;
}
}
//dfs建树↓
memset(fa,,sizeof(fa));
int s=min(n,);
d[s]=;
dfs(s);
//倍增↓
for(int i=;i<=n;++i)
{
// /cout<<i<<" "<<fa[i]<<endl;
f[i][]=fa[i];
mac[i][]=w[i];
}
for(int j=;j<=;++j)
for(int i=;i+(<<j)-<=n;++i)
{
f[i][j]=f[f[i][j-]][j-];
zz[]=mac[i][j-],zz[]=macc[i][j-];
zz[]=mac[f[i][j-]][j-],zz[]=macc[f[i][j-]][j-];
//这里用zz只是懒得写if
sort(zz+,zz+,cmpp);//从大到小sort一下
unique(zz+,zz+);//因为要严格第二大所以unique一下
mac[i][j]=zz[];
macc[i][j]=zz[];
}
long long ans=1e14+;
for(int i=;i<=m;++i)
if(!b[i].tag)//循环每条非树边
{
int u=b[i].x,v=b[i].y;
//倍增求lca
if(d[u]<d[v])swap(u,v);
for(int j=;j>=;--j)
if(d[u]-d[v]>=(<<j))
{
if(b[i].l>mac[u][j])//如果非树边比最长边长
ans=min(ans,sum-mac[u][j]+b[i].l);//这两条替换是一种可能方案
else if(b[i].l==mac[u][j])//否则如果非树边跟最长边一样长
ans=min(ans,sum-macc[u][j]+b[i].l);//把这条边跟第二长边替换是一种可能方案
u=f[u][j];//记得往上跳
}
if(u==v)continue;
for(int j=;j>=;--j)
if(f[u][j]!=f[v][j])
{
if(b[i].l>mac[u][j])
ans=min(ans,sum-mac[u][j]+b[i].l);
else if(b[i].l==mac[u][j])
ans=min(ans,sum-macc[u][j]+b[i].l);
u=f[u][j];
if(b[i].l>mac[v][j])
ans=min(ans,sum-mac[v][j]+b[i].l);
else if(b[i].l==mac[v][j])
ans=min(ans,sum-macc[v][j]+b[i].l);
v=f[v][j];
}
if(b[i].l>w[u])
ans=min(ans,sum-w[u]+b[i].l);
if(b[i].l>w[v])
ans=min(ans,sum-w[v]+b[i].l);
}
cout<<ans<<endl;//输出撒花
return ;
}

「LuoguP4180」 【模板】严格次小生成树[BJWC2010](倍增 LCA Kruscal的更多相关文章

  1. 「BJWC2010」模板严格次小生成树

    题目描述 小 \(C\) 最近学了很多最小生成树的算法,\(Prim\) 算法.\(Kruskal\) 算法.消圈算法等等.正当小\(C\)洋洋得意之时,小\(P\)又来泼小\(C\)冷水了.小\(P ...

  2. P4180 【模板】严格次小生成树[BJWC2010]

    P4180 [模板]严格次小生成树[BJWC2010] 倍增(LCA)+最小生成树 施工队挖断学校光缆导致断网1天(大雾) 考虑直接枚举不在最小生成树上的边.但是边权可能与最小生成树上的边相等,这样删 ...

  3. 【洛谷】4180:【模板】严格次小生成树[BJWC2010]【链剖】【线段树维护最大、严格次大值】

    P4180 [模板]严格次小生成树[BJWC2010] 题目描述 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说, ...

  4. Luogu P4180 【模板】严格次小生成树[BJWC2010]

    P4180 [模板]严格次小生成树[BJWC2010] 题意 题目描述 小\(C\)最近学了很多最小生成树的算法,\(Prim\)算法.\(Kurskal\)算法.消圈算法等等.正当小\(C\)洋洋得 ...

  5. POJ 1679 The Unique MST:次小生成树【倍增】

    题目链接:http://poj.org/problem?id=1679 题意: 给你一个图,问你这个图的最小生成树是否唯一. 题解: 求这个图的最小生成树和次小生成树.如果相等,则说明不唯一. 次小生 ...

  6. 洛谷 P4180 【模板】严格次小生成树[BJWC2010]【次小生成树】

    严格次小生成树模板 算法流程: 先用克鲁斯卡尔求最小生成树,然后给这个最小生成树树剖一下,维护边权转点权,维护最大值和严格次大值. 然后枚举没有被选入最小生成树的边,在最小生成树上查一下这条边的两端点 ...

  7. 【【模板】严格次小生成树[BJWC2010]】

    树上的路径怎么能没有树剖 显然,次小生成树和最小生成树只在一条边上有差距,于是我们就可以枚举这一条边,将所有边加入最小生成树,之后再来从这些并不是那么小的生成树中找到那个最小的 我们往最小生成树里加入 ...

  8. 【luogu P4180 严格次小生成树[BJWC2010]】 模板

    题目链接:https://www.luogu.org/problemnew/show/P4180 这个题卡树剖.记得开O2. 这个题inf要到1e18. 定理:次小生成树和最小生成树差距只有在一条边上 ...

  9. 【洛谷 P4180】【模板】严格次小生成树[BJWC2010](倍增)

    题目链接 题意如题. 这题作为我们KS图论的T4,我直接打了个很暴力的暴力,骗了20分.. 当然,我们KS里的数据范围远不及这题. 这题我debug了整整一个晚上还没debug出来,第二天早上眼前一亮 ...

随机推荐

  1. [转]screen 的使用

    当我们使用securecrt,putty, 等连接远程服务器时,如果正在执行一个程序,比如shell 脚本,退出当前的窗口会导致程序终止!其原理如下: 根据POSIX.1定义: 1 挂断信号(SIGH ...

  2. ssh无密码登陆权威指南

    [0]写在前面 由于ssh 实现的是免密码登陆,大致步骤是: 0.1) client通过ssh登陆到server: 0.2) server检查家目录下的.ssh文件, 并发送公钥文件 authoriz ...

  3. Oracle的循环和Corsor

    这两天啊有一个心的业务,是须要假设我批量改动数据的话,那么还有一张表的数据也须要改动.也是多条的改动,发现这个问题的时候.自然而然的想到了触发器,可是曾经都是简单的单条语句的跟新,没有过整个表的去做一 ...

  4. 【PHP开发】远程文件(图片)下载

    这一篇文章介绍的方法不算原创了,只是引用的别人的文章,加上自己的注释,因为接触php时间不长,所以尝试的东西比较多,自己加的注释也比较简单,php高手请略过. 我要用到远程下载图片,是在做微信公众平台 ...

  5. Kindeditor 修改内容时如何不让&nbsp;及 <> 被自动转义

    $html = str_replace(' ', '&nbsp;', $html); $html = str_replace('>', '&gt;', $html); $html ...

  6. Android OOM解决方案 :

    清单文件里 给Application标签加上android:largeHeap="true"这行代码   这样会给你的app分配一个大内存   如果某个页面在绘制时会耗非常多的内存 ...

  7. 【BZOJ4519】[Cqoi2016]不同的最小割 最小割树

    [BZOJ4519][Cqoi2016]不同的最小割 Description 学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分 ...

  8. 基于live555实现的RTSPServer对底层进行性能优化的方法

    在博客<EasyIPCamera高性能摄像机RTSP服务器RTSPServer解决方案>我介绍了基于live555实现的一套RTSPServer功能组件,当时开发者经过几个月的调试,已经将 ...

  9. 几句话搞懂URI、URL、URN之间的关系

    1.URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源. 2.RL是uniform resource locator,统一资源定位器,它是一种具体 ...

  10. 使用IntelliJ IDEA 15和Maven创建Java Web项目(转)

    1. Maven简介 相对于传统的项目,Maven 下管理和构建的项目真的非常好用和简单,所以这里也强调下,尽量使用此类工具进行项目构建, 它可以管理项目的整个生命周期. 可以通过其命令做所有相关的工 ...