最小生成树——Kruskal算法(C++)

 

源代码:

#include<cstdio>
int f[1001],xxx[1001],yyy[1001],i[1001],m,n,k(0);
long long ans(0);
void x1(int t1,int t2)
{
    int x=t1,y=t2,m=i[(t1+t2)/2],t;
    do
    {
      while (i[x]<m)
        x++;
      while (i[y]>m)
        y--;
      if (x<=y)
      {
        t=i[x];
        i[x]=i[y];
        i[y]=t;
        t=xxx[x];
        xxx[x]=xxx[y];
        xxx[y]=t;
        t=yyy[x];
        yyy[x]=yyy[y];
        yyy[y]=t;
        x++;
        y--;
      }
    }
    while (x<=y);
    if (x<t2)
      x1(x,t2);
    if (y>t1)
      x1(t1,y);
}
int x2(int t)
{
    if (f[t]==0)
      return t;
    f[t]=x2(f[t]);
    return f[t];
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int a=1;a<=m;a++)
      scanf("%d%d%d",&xxx[a],&yyy[a],&i[a]);
    x1(1,m);
    for (int a=1;a<=m;a++)
    {
      int t1,t2;
      t1=x2(xxx[a]);
      t2=x2(yyy[a]);
      if (t1!=t2)
      {
        k++;
        if (k==n)
          break;  //节点计数器,以节省时间。
        f[t2]=t1;
        ans+=i[a];
      }  //利用并查集对快排完的权值进行不同集合合并处理。
    }
    printf("%d",ans);
    return 0;
}

转载于:https://www.cnblogs.com/koruko/p/5100358.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最小生成树Kruskal算法是一种常用的图算法,用于找到一个连通图的最小生成树。下面是Kruskal算法C++代码示例: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; // 定义边的结构体 struct Edge { int src, dest, weight; }; // 定义并查集的数据结构 classFind { public: vector<int> parent, rank; UnionFind(int n) { parent.resize(n); rank.resize(n); for (int i = 0; i < n; i++) { parent[i] = i; rank[i] = 0; } } int find(int x) { if (parent[x] != x) { parent[x] = find(parent[x]); } return parent[x]; } void unionSet(int x, int y { int rootX = find(x); int rootY = find(y); if (rootX != rootY) { if (rank[rootX] < rank[rootY]) { parent[rootX] = rootY; } else if (rank[rootX] > rank[rootY]) { parent[rootY] = rootX; } else { parent[rootY] = rootX; rank[rootX]++; } } } }; // Kruskal算法实现 vector<Edge> kruskalMST(vector<Edge>& edges, int V) { // 按照边的权重进行排序 sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) { return a.weight < b.weight; }); vector<Edge> result; UnionFind uf(V); for (const Edge& edge : edges) { int src = edge.src; int dest = edge.dest; // 判断加入边后是否形成环路 if (uf.find(src) != uf.find(dest)) { uf.unionSet(src, dest); result.push_back(edge); } } return result; } int main() { int V, E; cout << "请输入顶点数和边数:"; cin >> V >> E; vector<Edge> edges(E); cout << "请输入每条边的起点、终点和权重:" << endl; for (int i = 0; i < E; i++) { cin >> edges[i].src >> edges[i].dest >> edges[i].weight; } vector<Edge> mst = kruskalMST(edges, V); cout << "最小生成树的边:" << endl; for (const Edge& edge : mst) { cout << edge.src << " - " << edge.dest << " : " << edge.weight << endl; } return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值