当前位置:网站首页>次小生成树
次小生成树
2022-07-05 04:36:00 【璀璨的秋叶】
.先求最小生成树,然后依次枚举非树边,然后将该边加入树中,同时从树中去掉一条边,使得最终图仍然是一棵树,统计最小值。
这个方法一定可以找到非严。证明如下
定义1:设T为图G的一棵生成树,对于非树边a和树边b,插入边a,并删除边b的操作记为(+a, -b)。如果T+a-b之后,仍然是一棵生成树,称(+a,-b)是T的一个可行交换。
定义2:称由T进行一次可行变换所得到的新的生成树集合称为T的邻集。
做法中的枚举外部边,删除树中边就是枚举MGT的邻集。
定理:次小生成树一定在最小生成树的邻集中
定理证明:
反证,如果有次小生成树与最小生成树不相同的有k条边,排序做kruskal,找到第一条和次小不同的边,在树中的边t连接ab。
我们将次小中连接ab中的一条边p去掉换成t,那么次小就会变得更小(因为排序kruskal)这样一个可行交换我们让次小生成树和最小生成树的不相同的边数k-1。这种操作可以持续做下去直到只差1条边。所以次小生成树一定在最小生成树的邻集中。
// 新生成树 newsum = sum - w(树内 2 点 之间的边) + w(树外 2 点之间的边)
//(1) 若 newsum < sum (则 sum 一定不是最小生成树边权和 矛盾)
// 所以 sum > newsum (严格次小生成树)
//(2) 若 w(树外 2 点之间的边) (a - b两点剑)不是最大的 那么 最小生成树 一定可以取到这条边
// 矛盾
// 所以 一定要取到 两点之间最大的边 来 替换新边
// 若新边 == 两点之间最大的边 则 取次大
```
#include <bits/stdc++.h>
using namespace std;
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define x first
#define y second
#define fr front
#define db double
//int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
//int dx[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
//int dy[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
//int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
//int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};
typedef pair<int, int> PII;
typedef long long LL ;
const int N = 10010, M = 510;
struct edge
{
int a, b, c, f;
bool operator< (edge x)
{
return c < x.c;
}
}g[N];
int n, m;
int h[M], e[N], w[N], ne[N], idx;// 存储最小生成树
int dist1[M][M], dist2[M][M];// 树中两点的最远距离 与 次远距离
int p[M];
void add(int a, int b, int c) // 添加一条边a->b,边权为c
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
int find(int x) // 并查集
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
void dfs(int u, int f, int m1, int m2, int ds1[], int ds2[])
{
ds1[u] = m1, ds2[u] = m2;
for (int i = h[u]; ~i ;i = ne[i])
{
int t = e[i];
if (t != f)
{
int td1 = m1, td2 = m2;
if (w[i] > td1) td2 = td1, td1 = w[i];
else if (w[i] < td1 && w[i] > td2) td2 = w[i];
dfs(t, u, td1, td2, ds1, ds2);
}
}
}
int main()
{
io;
memset(h, -1, sizeof h);
cin >> n >> m;
for (int i = 0;i < m;i ++ )
{
int a, b, c, f = 0;
cin >> a >> b >> c;
g[i] = {a, b, c, f};
}
for (int i = 1;i <= n;i ++ ) p[i] = i;
// 求最小生成树
sort(g, g + m);
LL sum = 0;
for (int i = 0;i < m;i ++ )
{
int a = g[i].a, b = g[i].b, c = g[i].c;
int x = find(a), y = find(b);
if (x != y)
{
add(a, b, c), add(b, a, c); // 存储次小生成树
g[i].f = 1; // 标记在树中
p[x] = y;
sum += c;
}
}
// 新生成树 newsum = sum - w(树内 2 点 之间的边) + w(树外 2 点之间的边)
//(1) 若 newsum < sum (则 sum 一定不是最小生成树边权和 矛盾)
// 所以 sum > newsum (严格次小生成树)
//(2) 若 w(树外 2 点之间的边) (a - b两点剑)不是最大的 那么 最小生成树 一定可以取到这条边
// 矛盾
// 所以 一定要取到 两点之间最大的边 来 替换新边
// 若新边 == 两点之间最大的边 则 取次大
// 求生成树中 两点的最远距离 与 次远距离
for (int i = 1;i <= n;i ++ ) dfs(i, -1, -1e9, -1e9, dist1[i], dist2[i]);
LL ans = 1e18;
for (int i = 0;i < m;i ++ )
if (!g[i].f) // 不止最小生成树里的边
{
int a = g[i].a, b = g[i].b, c = g[i].c;
LL t;
if (c > dist1[a][b])
t = sum + c - dist1[a][b];
else if (c > dist2[a][b])
t = sum + c - dist2[a][b];
ans = min(ans, t);
}
cout << ans << endl;
return 0;
}
边栏推荐
- PHP读取ini文件并修改内容写入
- 【虚幻引擎UE】运行和启动的区别,常见问题分析
- Interview related high-frequency algorithm test site 3
- [illusory engine UE] method to realize close-range rotation of operating objects under fuzzy background and pit recording
- 2022-2028 global and Chinese virtual data storage Market Research Report
- Rk3399 platform development series explanation (network debugging) 7.29 summary of network performance tools
- Function template
- 2022-2028 global and Chinese video coding and transcoding Market Research Report
- 揭秘技术 Leader 必备的七大清奇脑回路
- OWASP top 10 vulnerability Guide (2021)
猜你喜欢
【虚幻引擎UE】打包报错出现!FindPin错误的解决办法
[moteur illusoire UE] il ne faut que six étapes pour réaliser le déploiement du flux de pixels ue5 et éviter les détours! (4.26 et 4.27 principes similaires)
Power management bus (pmbus)
2022-2028 global and Chinese virtual data storage Market Research Report
level18
Key review route of probability theory and mathematical statistics examination
直播預告 | 容器服務 ACK 彈性預測最佳實踐
Serpentine matrix
MySQL in-depth learning - index creation and deletion, index design principles, index failure scenarios, query optimization, index push down ICP
Network layer - forwarding (IP, ARP, DCHP, ICMP, network layer addressing, network address translation)
随机推荐
Neural network and deep learning Chapter 1: introduction reading questions
Function template
How to force activerecord to reload a class- How do I force ActiveRecord to reload a class?
Managed service network: application architecture evolution in the cloud native Era
CUDA Programming atomic operation atomicadd reports error err:msb3721, return code 1
Leetcode hot topic Hot 100 day 33: "subset"
Sword finger offer 07 Rebuild binary tree
Leetcode 222 number of nodes of complete binary tree
Learning MVVM notes (1)
OWASP top 10 vulnerability Guide (2021)
Key review route of probability theory and mathematical statistics examination
Basic analysis of IIC SPI protocol
Sequelize. JS and hasmany - belongsto vs hasmany in serialize js
[crampon programming] lintcode decoding Encyclopedia - 1100 strange printer
All in one 1413: determine base
Web开发人员应该养成的10个编程习惯
A solution to the problem that variables cannot change dynamically when debugging in keil5
User behavior collection platform
About the prompt loading after appscan is opened: guilogic, it keeps loading and gets stuck. My personal solution. (it may be the first solution available in the whole network at present)
Neural networks and deep learning Chapter 5: convolutional neural networks reading questions