当前位置:网站首页>AcWing 1148. 秘密的牛奶运输 题解(最小生成树)
AcWing 1148. 秘密的牛奶运输 题解(最小生成树)
2022-07-06 18:00:00 【乔大先生】
AcWing 1148. 秘密的牛奶运输
解题思路:先找到最小生成树,计算出权值之和并标记所有最小生成树内的边。之后遍历所有边,找到包含两个点的路径的上的最大边和次大边并记录,(当两个点找到一条新的路径相连时,只有断开哪个最大边(t = sum - dist1[a][b] + w,dist1是最大边,得出的t才会是更小值,才能得出次小生成树),才能保证找到的是次小生成树,所以要记录最大边,记录次大边是为了防止最大边已经被用过),之后遍历所有非最小生成树内的边,依次替换树内的边,最终找到次小生成树
大佬题解原地址
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 510, M = 2e4 + 10;
int n, m;
int p[N]; //并查集
int dist1[N][N], dist2[N][N]; //分别记录对应边路径上的最大值和次大值
ll res = 1e18; //最终答案
ll sum; // 记录最小生成树的权值
int h[N], e[M], ne[M], w[M], idx; //记录树
struct Edge{
int a, b, w;
bool f; //标记这个边是否在最小生成树内
bool operator< (const Edge &t) const {
return w < t.w;
}
}edg[M];
void add(int a, int b, int c){
e[idx] = b;
ne[idx] = h[a];
w[idx] = c;
h[a] = idx ++ ;
}
int find(int x){
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
void dfs(int u, int fa, int mad1, int mad2, int d1[], int d2[]){
//找到每个点对应路径上个最大值和次大值
d1[u] = mad1, d2[u] = mad2; //d1、d2数组在此之前没有赋值
for(int i = h[u]; ~i; i = ne[i]){
int j = e[i];
if(j != fa){
int td1 = mad1, td2 = mad2;
if(w[i] > td1){
td2 = td1;
td1 = w[i];
}
else if(w[i] < td1 && w[i] > td2){
td2 = w[i];
}
dfs(j, u, td1, td2, d1, d2);
}
}
}
signed main()
{
cin>>n>>m;
memset(h, -1, sizeof h);
for(int i = 0; i < m; i ++ ){
int a, b, c;
cin>>a>>b>>c;
edg[i] = {
a, b, c};
}
//找到最小生成树
sort(edg, edg + m);
for(int i = 1; i <= n; i ++ ) p[i] = i;
for(int i = 0; i < m; i ++ ){
int a = edg[i].a, b = edg[i].b, w = edg[i].w; //这里要利用点去建图,所以a、b均用于表示自己
int pa = find(a), pb = find(b);
if(pa != pb){
sum += w;
p[pa] = pb;
add(a, b, w);
add(b, a, w);
edg[i].f = true;
}
}
//找到每个点对应路径的最大值和次大值
for(int i = 1; i <= n; i ++ ) dfs(i, -1, -1e9, -1e9, dist1[i], dist2[i]);
for(int i = 0; i < m; i ++ ){
if(!edg[i].f){
int a = edg[i].a, b = edg[i].b, w = edg[i].w;
ll t;
if(w > dist1[a][b]){
t = sum - dist1[a][b] + w;
}
else if(w > dist2[a][b]){
t = sum - dist2[a][b] + w;
}
res = min(res, t);
}
}
cout<<res<<endl;
return 0;
}
边栏推荐
- 736. Lisp 语法解析 : DFS 模拟题
- LeetCode. 剑指offer 62. 圆圈中最后剩下的数
- THREE.AxesHelper is not a constructor
- LeetCode:1175. Prime permutation
- The MySQL database in Alibaba cloud was attacked, and finally the data was found
- 2022 Google CTF SEGFAULT LABYRINTH wp
- Failed to successfully launch or connect to a child MSBuild. exe process. Verify that the MSBuild. exe
- Spark TPCDS Data Gen
- Taro applet enables wxml code compression
- Neon Optimization: summary of performance optimization experience
猜你喜欢
Instructions for using the domain analysis tool bloodhound
405 method not allowed appears when the third party jumps to the website
golang中的Mutex原理解析
【信号与系统】
1123. The nearest common ancestor of the deepest leaf node
Dark horse notes - exception handling
【案例分享】网络环路检测基本功能配置
shell脚本快速统计项目代码行数
The MySQL database in Alibaba cloud was attacked, and finally the data was found
Let's see through the network i/o model from beginning to end
随机推荐
【芯片方案设计】脉搏血氧仪
今日问题-2022/7/4 lambda体中修改String引用类型变量
Transformation transformation operator
Typical problems of subnet division and super network construction
Metauniverse urban legend 02: metaphor of the number one player
C language instance_ two
机器学习:随机梯度下降(SGD)与梯度下降(GD)的区别与代码实现。
Installation and testing of pyflink
修改px4飞控的系统时间
7.6模拟赛总结
LeetCode:1175. Prime permutation
Transplant DAC chip mcp4725 to nuc980
LeetCode. 剑指offer 62. 圆圈中最后剩下的数
C# 计算农历日期方法 2022
[JS] obtain the N days before and after the current time or the n months before and after the current time (hour, minute, second, year, month, day)
一起看看matlab工具箱内部是如何实现BP神经网络的
NEON优化:关于交叉存取与反向交叉存取
Js逆向——捅了【马蜂窝】的ob混淆与加速乐
C language - array
Clickhouse fields are grouped and aggregated, and SQL is queried according to the granularity of any time period