题目描述

小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. nginx 代理模式下,获取客户端真实IP

    最近做博友推荐,发现个小问题,用$_SERVER['REMOTE_ADDR'];得到的都是服务器的地址192.168.96.52,搜索了一下,发现问题,改为$_SERVER['HTTP_X_REAL_ ...

  2. PHP RSA加解密示例(转)

    1.生成密钥和公钥 开始前需要准备openssl环境 linux 需要安装openssl工具包,传送门http://www.openssl.org/source/ window 下需要安装openss ...

  3. ORACLE schedule job设置

    --创建job begin DBMS_SCHEDULER.CREATE_JOB ( job_name => 'APICALL_LOG_INTERFACE_JOB', job_type => ...

  4. 手把手实现andriod应用增量升级

    近期研究了android应用增量升级的应用.当中用到了android NDK编程,先说下为什么要使用增量升级.当我们的应用达到一定大小的时候,比方眼下有30M.假设新版本号35M仅仅是添加了几个功能, ...

  5. HTML5 2D平台游戏开发#3冲刺

    断断续续地把Demo又写了一阵,终于把角色的冲刺动作完成了.冲刺的作用是使角色能够快速移动,闪避攻击或障碍.其完成效果如下: 首先,仍需要一些变量来表示角色的冲刺状态: //标识角色是否处于冲刺中 v ...

  6. SQL注入基础入门

    一般的WEB架构 SQL注入成因: 用户开启浏览器并连接http://www.xxx.com.位于逻辑层的Web服务器从文件系统中加载脚本将其传递给脚本引擎,脚本引擎负责解析并执行脚本. 脚本使用数据 ...

  7. android 5.0 默认水波纹背景属性,可设置不论什么View

    actionBarItemBackground   5.0以上超出边界圆形水波纹 selectableItemBackground  5.0以上边界内圆形水波纹 这两个属性在5.0下面是默认的灰色效果 ...

  8. 世界更清晰,搜狐新闻客户端集成HUAWEI HiAI 亮相荣耀Play发布会!

    ​​6月6日,搭载有“很吓人”技术的荣耀Play正式发布,来自各个领域的大咖纷纷为新机搭载的惊艳技术站台打call,其中,搜狐公司董事局主席兼首席执行官张朝阳揭秘:华为和搜狐新闻客户端在硬件AI方面做 ...

  9. mnesia的脏写和事物写的测试

    在之前的文章中,测试了脏读和事物读之间性能差别,下面测试下脏写和事物写之间的性能差别: 代码如下: -module(mnesia_text). -compile(export_all). -recor ...

  10. WPF实现ScrollViewer滚动到指定控件处

    在前端 UI 开发中,有时,我们会遇到这样的需求:在一个 ScrollViewer 中有很多内容,而我们需要实现在执行某个操作后能够定位到其中指定的控件处:这很像在 HTML 页面中点击一个链接后定位 ...