每周算法:次小生成树

题目链接

秘密的牛奶运输

题目描述

农夫约翰要把他的牛奶运输到各个销售点。

运输过程中,可以先把牛奶运输到一些销售点,再由这些销售点分别运输到其他销售点。

运输的总距离越小,运输的成本也就越低。

低成本的运输是农夫约翰所希望的。

不过,他并不想让他的竞争对手知道他具体的运输方案,所以他希望采用费用第二小的运输方案而不是最小的。

现在请你帮忙找到该运输方案。

注意:

  • 如果两个方案至少有一条边不同,则我们认为是不同方案;
  • 费用第二小的方案在数值上一定要严格大于费用最小的方案;
  • 答案保证一定有解;

输入格式

第一行是两个整数 N , M N,M N,M,表示销售点数和交通线路数;

接下来 M M M 行每行 3 3 3 个整数 x , y , z x,y,z x,y,z,表示销售点 x x x 和销售点 y y y 之间存在线路,长度为 z z z

输出格式

输出费用第二小的运输方案的运输总距离。

样例 #1

样例输入 #1

4 4
1 2 100
2 4 200
2 3 250
3 4 100

样例输出 #1

450

提示

【数据范围】

1 ≤ N ≤ 500 1≤N≤500 1N500,
1 ≤ M ≤ 1 0 4 1≤M≤10^4 1M104,
1 ≤ z ≤ 1 0 9 1≤z≤10^9 1z109,
数据中可能包含重边。

算法思想

根据题目描述,求的是一棵严格次小生成树。所谓严格指的是该次小生成树的总边权严格大于最小生成树的边权之和。如果次小生成树的总边权大于等于最小生成树的边权之和,那么可以称为非严格次小生成树

要求次小生成树,可以先求最小生成树,然后枚举非树边(不在最小生成树中的边),尝试将该边加入树中,同时从树中去掉一条边,保证最终仍然是一棵树。统计所有这些树的边权之和的最小值就是次小生成树。如下图所示:在这里插入图片描述
该算法的基本思想如下:

  • 使用Kruskal算法求图中的最小生成树,边权之和 s u m sum sum;并标记每条边是否在最小生成树中;同时构建出最小生成树。
  • 预处理最小生成树中任意两点之间代价最大的边的边权 d 1 [ a , b ] d1[a,b] d1[a,b]和代价次大的边的边权 d 2 [ a , b ] d2[a, b] d2[a,b],便于将来用非树边去替换。
  • 依次枚举所有不在最小生成树中的边 a ↔ b a \leftrightarrow b ab,边权为 c c c。尝试用该边替换节点 a a a到节点 b b b的路径中的一条边,显然要选代价最大或者次大的那条边。
    • 如果 c > d 1 [ a , b ] c > d1[a,b] c>d1[a,b],可以用该边替换 a a a b b b路径中代价最大的那条边,替换之后的总权值为 s u m − d 1 [ a , b ] + c sum-d1[a,b]+c sumd1[a,b]+c
    • 否则如果 c < d 1 [ a , b ] c<d1[a,b] c<d1[a,b]并且 c > d 2 [ a , b ] c >d2[a,b] c>d2[a,b],可以用该边替换 a a a b b b路径中代价次大的那条边,替换后的总价值为 s u m − d 2 [ a , b ] + c sum-d2[a,b]+c sumd2[a,b]+c
  • 求所有替换之后总权值的最小值,就是次小生成树。

时间复杂度

Kruskal算法的时间复杂度为 O ( m l o g m ) O(mlogm) O(mlogm),预处理最小生成树中任意两点之间代价最大和次大的边的时间复杂度为 O ( n 2 ) O(n^2) O(n2)

代码实现

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 505, M = 1e4 + 5;
struct E {int a, b, c;bool f; //表示是否在最小生成树中bool operator < (const E &e) const { return c < e.c; }
}edge[M];
int n, m;
int p[N], d1[N][N], d2[N][N];
int h[N], e[M], w[M], ne[M], idx;
int find(int x)
{if(x != p[x]) p[x] = find(p[x]);return p[x];
}
void add(int a, int b, int c)  // 添加一条边a->b,边权为c
{e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}//预处理生成树中u点到其它点之间所有边中边权最大值d1[u][v]和次大值d2[u][v]
void dfs(int u, int fa, int maxd1, int maxd2, int d1[], int d2[])
{d1[u] = maxd1, d2[u] = maxd2;for(int i = h[u]; ~ i; i = ne[i]){int v = e[i];if(v != fa) //避免往回搜索 {int t1 = maxd1, t2 = maxd2;if(w[i] > t1) t2 = t1, t1 = w[i];else if(w[i] < t1 && w[i] > t2) t2 = w[i];dfs(v, u, t1, t2, d1, d2);}}
}
int main()
{cin >> n >> m;for(int i = 0; i < m; i ++) cin >> edge[i].a >> edge[i].b >> edge[i].c;memset(h, -1, sizeof h);//最小生成树sort(edge, edge + m);for(int i = 1; i <= n; i ++) p[i] = i;LL sum = 0;for(int i = 0; i < m; i ++){int a = edge[i].a, b = edge[i].b, c = edge[i].c;int pa = find(a), pb = find(b);if(pa != pb){p[pa] = pb;sum += c;add(a, b, c), add(b, a, c); //构建最小生成树edge[i].f = true;}}//处理最小生成树种任意两点间所有边中边权的最大值和次大值,注意最大值和次大值初始化尽可能小for(int i = 1; i <= n; i ++) dfs(i, -1, -1e9, -1e9, d1[i], d2[i]);LL ans = 1e18;//枚举所有不在最小生成树中的边for(int i = 0; i < m; i ++){if(!edge[i].f) {int a = edge[i].a, b = edge[i].b, c = edge[i].c;//尝试边i替换a-b的路径中最大的一条边LL t = 1e18;if(c > d1[a][b]) t = sum - d1[a][b] + c;else if(c > d2[a][b]) t = sum - d2[a][b] + c;ans = min(ans, t);}}cout << ans << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/19590.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【面试】介绍一下HotSpot虚拟机

目录 1. 说明2. 起源与发展3. 技术特点3.1 热点代码探测技术3.2 内存管理3.3 垃圾收集器3.4 并发和多线程支持3.5 指令重排优化 4. 执行模式与性能 1. 说明 1.HotSpot虚拟机是一款由Oracle JDK和OpenJDK广泛使用的Java虚拟机&#xff08;JVM&#xff09;。2.HotSpot虚拟机凭借…

react 动态form表单

需求在日常开发中反复写form 是一种低效的开发效率&#xff0c;布局而且还不同这就需要我们对其封装 为了简单明了看懂代码&#xff0c;我这里没有组件&#xff0c;都放在一起&#xff0c;简单抽离相信作为大佬的你&#xff0c;可以自己完成&#xff0c; 首先我们做动态form …

Gartner发布电信运营商应对持续变化的网络安全环境指南:现代云安全与网络安全的五大核心挑战

所有组织的云和网络都面临着高级威胁。作为网络安全的关键参与者&#xff0c;电信运营商的 CIO 需要了解行业面临的挑战&#xff0c;并了解应采用哪些解决方案来实现方法的现代化。 主要发现 电信运营商 (CSP) CIO 如果不能调整其安全策略来保护其环境&#xff0c;那么他们将会…

单片机之从C语言基础到专家编程 - 4 C语言基础 - 4.13数组

C语言中&#xff0c;有一类数据结构&#xff0c;它可以存储一组相同类型的元素&#xff0c;并且可以通过索引访问这些元素&#xff0c;没错&#xff0c;这类数据结构就是数组。数组可以说是C语言中非常重要的数据结构之一了。使用数组可以是程序逻辑更加清晰&#xff0c;也更加…

IDEA 中导入脚手架后该如何处理?

MySQL数据库创建啥的&#xff0c;没啥要说的&#xff01;自行配置即可&#xff01; 1.pom.xml文件&#xff0c;右键&#xff0c;add Maven Project …………&#xff08;将其添加为Maven&#xff09;【下述截图没有add Maven Project 是因为目前已经是Maven了&#xff01;&…

react useState基本使用

1. React Hooks介绍 React Hooks是React 16.8版本引入的新特性&#xff0c;它允许在不编写类的情况下使用state和其他React特性。Hooks的引入极大地简化了组件的编写&#xff0c;使得函数式组件能够拥有类似类组件的功能。 1.1 函数式组件与类组件的区别 函数式组件与类组件…

LNMP安装部署

yum -y install ncurses ncurses-devel bison cmake openssl-devel gcc gcc-c make 方法二

差旅游记|绵阳印象:与其羡慕他人,不如用力活好自己。

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 来绵阳之前同事就问: “雷工&#xff0c;能吃辣嘛&#xff1f;”。 “还行&#xff0c;能吃点辣。” “那你去了四川别说能吃点辣&#xff0c;那边的能吃点比跟你说的能吃点不太一样” 01 你好 今天打车&#xff0c;上…

这篇文章让你彻底了解如何实用tcpdump 抓包

直接看例子&#xff1a; tcpdump tcp-i ens33 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap &#xff08;1&#xff09;tcp∶ ip icmp arp rarp 和 tcp、udp、icmp这些选项等都要放到第一个参数的位置&#xff0c;用来过滤数据报的类型 &…

Go 语言中常量和变量的定义、使用

Go 语言&#xff0c;作为一种现代编程语言&#xff0c;以其简洁性和高效性赢得了开发者的青睐。在 Go 语言中&#xff0c;常量与变量作为存储和操作数据的基本元素&#xff0c;扮演着至关重要的角色。通过正确理解和使用常量与变量&#xff0c;开发者可以编写出更加健壮和高效的…

「多客」圈子论坛社区交友系统开源版小程序源码|圈子社区系统

简述 社交圈子论坛系统是一种面向特定人群或特定话题的社交网络&#xff0c;它提供了用户之间交流、分享、讨论的平台。在这个系统中&#xff0c;用户可以创建、加入不同的圈子&#xff0c;圈子可以是基于兴趣、地域、职业等不同主题的。用户可以在圈子中发帖、评论、点赞等互…

抖音太可怕了,我卸载了

这两天刷短视频&#xff0c;上瘾了&#xff0c;太可怕了。 自己最近一直在研究短视频制作&#xff0c;所以下载了抖音&#xff0c;说实话&#xff0c;我之前手机上并没有抖音&#xff0c;一直在用B站。 用了两天抖音&#xff0c;我发现&#xff0c;这玩意比刷B站还容易上瘾啊…

国产GPU算力公司及产品

目前&#xff0c;中国有多家从事国产算力GPU研发与生产的企业&#xff0c;以下是一些代表性的公司及其相关产品概述&#xff1a; 景嘉微&#xff1a; 近期&#xff0c;景嘉微宣布成功研发了“景宏系列”AI算力产品&#xff0c;该系列面向AI训练、AI推理、科学计算等领域&#x…

Centos 7下的VulFocus靶场搭建详细教程

一、靶场介绍 自带 Flag 功能&#xff1a;每次启动 flag 都会自动更新&#xff0c;明确漏洞是否利用成功。带有计分功能。兼容 Vulhub、Vulapps 中所有漏洞镜像。 二、下载安装 下载 VMware 软件下载 centos镜像 三、Docker知识 学习链接&#xff1a;https://www.runoob.c…

chrome调试手机网页

前期准备 1、 PC端安装好chrmoe浏览器 2、 安卓手机安装好chrmoe浏览器 3、 数据线 原文地址&#xff1a;https://lengmo714.top/343880cb.html 手机打开调试模式 进入手机设置&#xff0c;找到开发者模式&#xff0c;然后启用USB调试 打开PC端chrome调试功能 1、点击chr…

【康耐视国产案例】AI视觉相机创新 加速商超物流数智化转型

连锁商超/零售店正面临着因消费者购物习惯改变等挑战&#xff0c;迎来了以新兴技术崛起而催生的数字化物流体系转型需求。物流行业与AI机器视觉的深度融合&#xff0c;解决了传统机器视觉识别速度慢、环境要求高、定制化部署耗时过多等痛点&#xff0c;大大提高了物流供应链的效…

GD32F470+lwip 丢包问题分析及解决

最近在用GD32和管理机之间用TCP协议开发一个功能&#xff0c;功能都没问题&#xff0c;后面跑大量发包时候的连续测试时&#xff0c;总是会出现偶发性的&#xff0c;大概几分钟到数十分钟的一次丢包。尽管在应用层做了超时机制&#xff0c;一旦超时就会重新建立socket链接并重新…

QT系列教程(6) 几种标准对话框

几种标准对话框 本文介绍几种标准对话框&#xff0c;都是Qt封装好的&#xff0c;我们先创建一个界面&#xff0c;添加几个按钮&#xff0c;然后分别在几个按钮的回调函数里添加创建不同对话框的逻辑 颜色对话框 颜色对话框用来选择颜色&#xff0c;创建后会显示各种颜色和透明…

GPT-4o:人工智能的新里程碑

GPT-4o&#xff0c;作为OpenAI最新推出的人工智能技术&#xff0c;无疑在人工智能领域掀起了新一轮的浪潮。这款新型的语言模型不仅继承了GPT系列的核心优势&#xff0c;更在多个方面实现了突破性的进展。以下&#xff0c;我们将从版本间的对比分析、GPT-4o的技术能力以及个人整…

html中table的替代方案

使用插件&#xff0c;2个功能强大的table插件 DataTables | Javascript table library 专门的table处理插件&#xff0c;下载时可以配置是否支持bootstrap和jquery ui等。参数众多。表格组件 table - Layui 文档 国内的插件&#xff0c;只支持jquery&#xff0c;配合默认的layu…