次小生成树 详解及模板 (仅kruskal)
思路
关于次小生成树,首先求出最小生成树,然后枚举每条不在最小生成树上的边(在原本的节点上添加一个vis属性进行判断即可),并把这条边放到最小生成树上面,然后就一定会形成环,那么我们在这条环路中取出一条(除了新加入的那一条边)最长的路(这里可以用d[u][v]来维护)。最终得到的权值就是次小生成树的权值。
实现
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx = 200 + 5;
const int mamx = 1e5 + 5;
int n, m, u, v, w, k;
int f[manx], d[manx][manx]; //d数组用来维护u到v的距离,在枚举边的时候会用到
vector<int>p[manx]; //扩展路径,path数组,缩写p
struct node {
int u, v, w;
bool vis; //比常规最小生成树多了vis属性判断边是否加入最小生成树的集合
}a[mamx];
bool cmp(node a, node b){
return a.w < b.w;
}
int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
int main()
{
int t; cin >> t;
while (t--){
k = 0;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) { //初始化操作,万物之父皆自己
p[i].clear();
p[i].push_back(i);
f[i] = i;
}
for (int i = 1; i <= m; i++){
scanf("%d%d%d", &u, &v, &w);
a[++k].u = u, a[k].v = v, a[k].w = w, a[i].vis = false;
}
sort(a + 1, a + 1 + k, cmp);
ll ans = 0;
int total = 1;
for (int i = 1; i <= k; i++){
u = find(a[i].u), v = find(a[i].v);
if (u == v) continue;
ans += a[i].w;
f[u] = v;
a[i].vis = 1; //标记进去最小生成树的集合
total++;
int l1 = p[u].size(), l2 = p[v].size();
for (int j = 0; j < l1; j++)
for (int k = 0; k < l2; k++)
d[p[u][j]][p[v][k]] = d[p[v][k]][p[u][j]] = a[i].w; //记录最小生成树中扩展路径的距离
for (int j = 0; j < l1; j++) p[v].push_back(p[u][j]); //合并路径
if (total == n) break;
}
ll res = inf; //次小生成树的集合
for (int i = 1; i <= k; i++)
if (!a[i].vis) //枚举每条没加入最小生成树的集合
res = min(res, ans + a[i].w - d[a[i].u][a[i].v]);
//ans是最小生成树的权值,减去最小生成树中u到v这条边的权值,加上枚举的这一条边进行比较
if (res > ans) cout << ans << endl;
else cout << "Not Unique!" << endl;
}
return 0;
}
次小生成树 详解及模板 (仅kruskal)的更多相关文章
- 最小生成树(次小生成树)(最小生成树不唯一) 模板:Kruskal算法和 Prim算法
Kruskal模板:按照边权排序,开始从最小边生成树 #include<algorithm> #include<stdio.h> #include<string.h> ...
- Angular6 学习笔记——组件详解之模板语法
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
- 算法笔记--sg函数详解及其模板
算法笔记 参考资料:https://wenku.baidu.com/view/25540742a8956bec0975e3a8.html sg函数大神详解:http://blog.csdn.net/l ...
- tp6源码解析-第二天,ThinkPHP6编译模板流程详解,ThinkPHP6模板源码详解
TP6源码解析,ThinkPHP6模板编译流程详解 前言:刚开始写博客.如果觉得本篇文章对您有所帮助.点个赞再走也不迟 模板编译流程,大概是: 先获取到View类实例(依赖注入也好,通过助手函数也好) ...
- 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解 (旧版本 | 仅作参考)
. 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...
- Delphi中TApplication详解(转仅供自己参考)
转自:http://blog.sina.com.cn/s/blog_4d6f55d90100bmv9.html TApplication是用于Delphi应用程序的类型,该类在单元forms中声明.T ...
- Python时间获取详解,Django获取时间详解,模板中获取时间详解(navie时间和aware时间)
1.Python获取到的时间 import pytz from datetime import datetime now = datetime.now() # 这个时间为navie时间(自己不知道自己 ...
- AC自动机详解 (P3808 模板)
AC自动机笔记 0.0 前言 哇,好久之前就看了 KMP 和 Trie 树,但是似乎一直没看懂 AC自动机?? 今天灵光一闪,加上之前看到一些博客和视频,瞬间秒懂啊... 其实这个玩意还是蛮好理解的. ...
- spring applicationContext.xml详解及模板
applicationContext.xml 文件 1.<context:component-scan base-package="com.eduoinfo.finances.ba ...
随机推荐
- hadoop环境搭建:完全分布式
目录 1.硬件配置 2.软件版本 3.准备工作 3.1.建立虚拟机,网络设置为桥接模式 3.2.更改主机名 3.3.绑定主机名和IP,建立各主机间的联系 3.4.关闭防火墙 3.5.配置宿主机host ...
- 1063 Set Similarity——PAT甲级
1063 Set Similarity Given two sets of integers, the similarity of the sets is defined to be Nc/Nt*10 ...
- 653. 两数之和 IV - 输入 BST + HashSet
653. 两数之和 IV - 输入 BST 题目描述 题解分析 最简单的方法就是遍历整棵树,找出所有可能的组合,判断是否存在和为 kk 的一对节点.现在在此基础上做一些改进. 如果存在两个元素之和为 ...
- 剑指 Offer 57 - II. 和为s的连续正数序列 + 双指针 + 数论
剑指 Offer 57 - II. 和为s的连续正数序列 Offer_57_2 题目描述 方法一:暴力枚举 package com.walegarrett.offer; /** * @Author W ...
- 剑指 Offer 56 - II. 数组中数字出现的次数 II + 位运算
剑指 Offer 56 - II. 数组中数字出现的次数 II Offer_56_2 题目详情 解题思路 java代码 package com.walegarrett.offer; /** * @Au ...
- javascript处理HTML的Encode(转码)和解码(Decode)
HTML的Encode(转码)和解码(Decode)在平时的开发中也是经常要处理的,在这里总结了使用javascript处理HTML的Encode(转码)和解码(Decode)的常用方式 一.用浏览器 ...
- Windows下常用测试命令
(1)ping 127.0.0.1 (测试本地网卡,127.0.0.1是本地循环地址,如果本地址无法Ping通,则表明本地机TCP/IP协议不能正常工作) (2)ping 127.0.0.1 - ...
- org.springframework.web.util.IntrospectorCleanupListener作用
回收那些不会主动回收,导致内存泄漏的垃圾,如javabeans
- POJ_2828 Buy Tickets 【线段树】
一.题目 Buy Tickets 二.分析 首先可以明确的是每个人的位置都是定的,那么如果从输入数据从后往前看,最后面的人进来的时候,他前面的人数肯定是定的. 那么可以考虑,当从后往前推时,这个人插入 ...
- Hznu_0j 1533 计算球体积(水)
题意:根据输入的半径值,计算球的体积: Input 输入数据有多组,每组占一行,每行包括一个实数,表示球的半径. Output 输出对应的球的体积,对于每组输入数据,输出一行,计算结果保留三位小数. ...