标签:int Kruskal 最小 生成 connections -- 节点
什么是图的最小生成树(min span tree ,MST)
对于有N个节点的图,边数最多 有 N*(N-1)/2 , 如果只是希望所有节点都连通, N-1条边就够了
所谓最小生成树指的是在所有N-1条边的连通图中,边的权值和最小的就是最小生成图
Kruskal 寻找最小生成图
- 所有边进行排序 ,得到边的序列 [10,20,30,40,80,90,91, 100]
- 取 [10] 这条边 , 1--4
- 取 [20] 这条边 , 1--4--2
- 取 [30] 这条边 , 1--4--2--5
- 取 [40] 这条边 , 对于节点1 和 节点5 ,它们已经是一个连通块了 ,不应该取这条边
- 取 [80] 这条边 , 节点3 不在已经形成的连通块1--4--2--5, 这条表可以取
7.至此,总共取了4条边, 满足N-1条边的要求,最小生成图找到了,即边集合 {[10],[20] ,[30] [80] }
根据上面的分析如何快速判断两个节点是否位于一个连通块是关键
请查看本人所写 并查集 求连通图问题。
OK,开始实际问题分析并给出C++代码
//see https://michael.blog.csdn.net/article/details/107796632
class dsu
{
vector<int> f;
public:
dsu(int n)
{
f.resize(n);
for(int i = 0; i < n; ++i)
f[i] = i;
}
void merge(int a, int b)
{
int fa = find(a);
int fb = find(b);
f[fa] = fb;
}
int find(int a)
{
int origin = a;
while(a != f[a])
{
a = f[a];
}
return f[origin] = f[a];
}
};
class Solution {
public:
vector<vector<int>> findCriticalAndPseudoCriticalEdges(int N, vector<vector<int>>& connections) {
//
dsu u(N+1);
sort(connections.begin(), connections.end(),[&](auto a, auto b){
return a[2] < b[2];//距离短的边优先
});
int edge = 0, p1, p2, dis, total = 0;
for(int i = 0; i < connections.size(); ++i)
{
p1 = connections[i][0];
p2 = connections[i][1];
dis = connections[i][2];
if(u.find(p1) != u.find(p2))//两个还未链接
{
u.merge(p1,p2);
edge++;
total += dis;
}
if(edge == N-1)
break;
}
auto MST= ( edge==N-1 ? total : -1);
std::cout << MST;
return {};
}
};
题目描述
- 找到最小生成树里的关键边和伪关键边
给你一个 n 个点的带权无向连通图,节点编号为 0 到 n-1 ,同时还有一个数组 edges ,其中 edges[i] = [fromi, toi, weighti] 表示在 fromi 和 toi 节点之间有一条带权无向边。最小生成树 (MST) 是给定图中边的一个子集,它连接了所有节点且没有环,而且这些边的权值和最小。
请你找到给定图中最小生成树的所有关键边和伪关键边。如果从图中删去某条边,会导致最小生成树的权值和增加,那么我们就说它是一条关键边。伪关键边则是可能会出现在某些最小生成树中但不会出现在所有最小生成树中的边。
请注意,你可以分别以任意顺序返回关键边的下标和伪关键边的下标。
标签:int,Kruskal,最小,生成,connections,--,节点 来源: https://www.cnblogs.com/boyang987/p/14794549.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。