克鲁斯卡尔算法 判断回路中的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了克鲁斯卡尔算法 判断回路中的问题相关的知识,希望对你有一定的参考价值。

这个是百度百科中给的程序,有一个小问题请大侠们帮忙。不用给代码,解释下就行了。

void kruskal (edgeset ge, int n, int e)
// ge为权按从小到大排序的边集数组
int set[MAXE], v1, v2, i, j;
for (i=1;i<=n;i++)
set[i]=0; // 给set中每个元素赋初值
i=1; // i表示获取的生成树中的边数,初值为1
j=1; // j表示ge中的下标,初始值为1
while (j<n && i<=e)
// 检查该边是否加入到生成树中

v1=seeks(set,ge[i].bv);
v2=seeks(set,ge[i].tv);
if (v1!=v2) // 当v1,v2不在同一集合,该边加入生成树

printf(“(%d,%d)”,ge[i].bv,ge[i].tv);
set[v1]=v2; //////这句话是说把两个节点的根节点串起来,为什么不是set[ge[i].bv]=set[ge[i].tv]呢?这样不是更清楚易懂吗?
j++;

i++;


if (v1!=v2) // 当v1,v2不在同一集合,该边加入生成树

printf(“(%d,%d)”,ge[i].bv,ge[i].tv);
set[v1]=v2; //////这句话是说把两个节点的根节点串起来,为什么不是set[ge[i].bv]=set[ge[i].tv]呢?这样不是更清楚易懂吗?
j++;

参考技术A 看这段代码真令我头疼,我就告诉你思路吧!
并查集你会不会?如果会的话那就好办。
kruskal算法用到了一种贪心策略,首先要把边集数组以边的权值从小到大排序,然后一条边一条边的查找,如果边的两个端点不在一个集合内,则将此边添加到正在生长的树林中,并合并两个端点所在的集合,直到最小生成树已生成完毕。
核心伪代码如下(本人不习惯给完整的可编译的代码):
func root(x:longint):longint;//查找i节点所在集合
var i,j,k:longint;
i:=x;j:=x;
while i!=f[i] do i=f[i];
while j!=i do
k=j;j=f[j];f[k]=i;//路径压缩,若不压缩效率将很低
;//root
proc union(i,j,c:longint);
var x,y:longint;
x=root(i);
y=root(j);
if x!=y then inc(ans,c);inc(temp);f[y]=x;
//若i和j分属两棵子树,则将此边添加到森林中,并合并其所在集合
;//union;
将边集数组按照边的权值从小到大排序;
for (i=1,i++,i=n) f[i]=i;//并查集初始化
for (i=1,i++,i=m)
union(edge[i].x,edge[i].y,edge[i].z);
if temp==n-1 then break;
//若temp==n-1则最小生成树已生成完毕,退出
//kruskal
if temp==n-1 then writeln(ans)//输出最小生成树的权值和
else writeln('No solution!');//若temp!=n-1,则说明此图为非连通图本回答被提问者和网友采纳

以上是关于克鲁斯卡尔算法 判断回路中的问题的主要内容,如果未能解决你的问题,请参考以下文章

克鲁斯卡尔算法一定要画图吗

C语言 克鲁斯卡尔算法怎么判断是不是构造成回路?求大手解答

克鲁斯卡尔算法的介绍

C语言数据结构 克鲁斯卡尔算法求无向网的最小生成树。

Kruskal算法 (克鲁斯卡尔)

最小生成树之克鲁斯卡尔(Kruskal)算法