kruskal算法形成回路判断的注意点

    //返回第i个顶点的终点 用于判断是否有相同的终点即形成回路
    private static int getEnd(int[] ends,int i){
//        if (ends[i] != 0){
//            i = ends[i];
//        }这里一定要注意用while循环不然后面的边连上了前面连上的边 最终节点只是该一小段的值
        //但是用了while循环后就可以一直找到前面连起来的最终节点  比如先连 E F  在连 CD  再练DE 这时候其实CDEF的最终节点都是F
        //如果没有用while 那么在连CE的时候会认为C的最终节点是 D  或者这里的E  其实 是F
        while (ends[i] != 0 ){
            i = ends[i];//意思就是只有i这个点有终点 那么i的终点就是终点的终点
        }
         return i;
    }

获取一条边每个节点的最终节点值

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kruskal算法是一种最小生成树算法,它的基本思想是将所有的边按照权值从小到大排序,然后依次加入生成树中,如果加入该边不会导致生成树形成环,则加入该边,否则舍去该边。 在Kruskal算法中,需要判断当前加入的边是否会导致生成树形成环。可以使用并查集来实现该功能。具体来说,对于每个节点,维护它的父节点,初始时每个节点的父节点都是它本身。每次加入一条边时,判断该边的两个端点是否在同一个并查集中,如果是,则加入该边会导致生成树形成环,应该舍去该边;否则,将两个端点所在的并查集合并起来,并将该边加入生成树中。 以下是使用链表实现的Kruskal算法判断回路的C++代码: ```cpp #include <iostream> #include <vector> using namespace std; struct Edge { int u, v, w; Edge(int _u, int _v, int _w) : u(_u), v(_v), w(_w) {} }; struct Node { int parent; int rank; Node() : parent(-1), rank(0) {} }; vector<Node> nodes; // 查找节点x所在的集合的代表节点 int find(int x) { if (nodes[x].parent == -1) { return x; } else { return nodes[x].parent = find(nodes[x].parent); } } // 合并x和y所在的集合 void merge(int x, int y) { int root_x = find(x); int root_y = find(y); if (root_x != root_y) { if (nodes[root_x].rank < nodes[root_y].rank) { nodes[root_x].parent = root_y; } else if (nodes[root_x].rank > nodes[root_y].rank) { nodes[root_y].parent = root_x; } else { nodes[root_y].parent = root_x; nodes[root_x].rank++; } } } // 判断加入边(u, v, w)是否形成环 bool hasCycle(int u, int v) { int root_u = find(u); int root_v = find(v); if (root_u == root_v) { return true; } else { merge(root_u, root_v); return false; } } // Kruskal算法求最小生成树 vector<Edge> kruskal(int n, vector<Edge>& edges) { vector<Edge> result; nodes.resize(n); sort(edges.begin(), edges.end(), [](Edge& e1, Edge& e2) { return e1.w < e2.w; }); for (auto& edge : edges) { if (!hasCycle(edge.u, edge.v)) { result.push_back(edge); } } return result; } int main() { int n = 6; vector<Edge> edges = { {0, 1, 4}, {0, 2, 3}, {1, 2, 1}, {1, 3, 2}, {2, 3, 4}, {3, 4, 2}, {4, 5, 6} }; vector<Edge> result = kruskal(n, edges); for (auto& edge : result) { cout << edge.u << " " << edge.v << " " << edge.w << endl; } return 0; } ``` 以上代码中,find函数和merge函数分别实现了并查集中的查找和合并操作。hasCycle函数判断加入边(u, v, w)是否会导致生成树形成环,如果是,则返回true,否则返回false,并且将u和v所在的集合合并起来。kruskal函数实现了Kruskal算法,其中使用sort函数将所有边按照权值从小到大排序,并依次加入生成树中。最后,将生成树的边保存在result向量中,并返回。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值