鱼C论坛

 找回密码
 立即注册
查看: 744|回复: 1

[已解决]克鲁斯卡尔算法求助!

[复制链接]
发表于 2021-9-7 11:35:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
代码是残缺的,希望有大佬能帮帮我

城市间道路铺设问题
实现图的最小生成树问题的克鲁斯卡尔算法。

输入:
第一行两个整数,分别表示顶点个数n和边数m,从第二行到第m+1行,每行三个整数分别表示每条边的两个顶点号及权值。
6 10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6

输出:
依次输出选中的n-1条边及最小生成树的权值之和
1 3 1
4 6 2
2 5 3
3 6 4
2 3 5
15


  1. #include<bits\stdc++.h>
  2. using namespace std;

  3. struct edge{
  4.         int u,v,weight;
  5. }e[100];

  6. void initialize(int n){
  7.         for(int i=0;i<n;i++){
  8.                
  9.         }
  10. }

  11. int Find(int i){
  12.        
  13. }

  14. void merge(int i,int j){
  15.         if() return false;
  16.         return true;
  17. }

  18. int Kruskal(int n, **e){
  19.         int k,j,a,b;
  20.         Sort(e, weight);  //将边按权重从小到大排序
  21.         initialize(n);    //初始时每个顶点为一个集合
  22.         k = j =1;            //k累计已选边的数目,j为所选的边在e中的序号
  23.         while (k < n){      //选择n - 1条边
  24.                 a = Find(e[j]);
  25.                 b = Find(e[j]);  //找出第j条边两个端点所在的集合
  26.                  if (a != b) {            //若不同,第j条边放入树中并合并这两个集合
  27.                         t[k++] = j;
  28.                         merge(a, b);
  29.                 }  
  30.                 j++;
  31.         }
  32. } //继续考察下一条边

  33. int main(){
  34.         int n,m;
  35.         printf("请输入顶点个数n和边数m\n");
  36.         scanf("%d%d",&n,&m);
  37.         printf("\n请输入每条边对应的顶点号以及对应的权值\n");
  38.         int i,j;
  39.         for (i=0;i<m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].weight);

  40.    
  41.         return 0;
  42. }
复制代码
最佳答案
2021-9-7 21:18:23
  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. #define IOS \
  6.     ios::sync_with_stdio(false); \
  7.     cin.tie(0); \
  8.     cout.tie(0)
  9. const int N = 1e5+5,M = 2e5+5;
  10. int n,m;
  11. int p[N],path[N];

  12. int find(int a){
  13.     if (p[a] != a) p[a] = find(p[a]);
  14.     return p[a];
  15. }

  16. struct Edge{
  17.     int a,b,w;// 需要对边排序,用结构体存储
  18.     bool operator< (const Edge& W) const{
  19.         return w < W.w;// 重载小于号
  20.     }
  21. }edge[M];

  22. int kruskal(){
  23.     sort(edge + 1,edge + m + 1);// 数组从下标为1开始存边
  24.     for (int i = 1; i <= n; i ++ ) p[i] = i;// 初始化并查集
  25.    
  26.     int res = 0,cnt = 0;// res存放最小生成树的边权之和,cnt存放最小生成树的边数
  27.     for (int i = 1;i <= m;i ++){
  28.         int a = edge[i].a,b = edge[i].b,w = edge[i].w;
  29.         a = find(a),b = find(b);
  30.         if (a != b){
  31.             p[a] = b;
  32.             res += w;
  33.             cnt ++;
  34.             path[cnt] = i;
  35.         }// n个点一共n-1条边
  36.         if (cnt == n-1) break;// 处理完提前退出
  37.     }
  38.     return res;
  39. }

  40. int main(){
  41.     IOS;
  42.    
  43.     cin >> n >> m;
  44.     int u,v,w;
  45.     for (int i = 1; i <= m; i ++ ){
  46.         cin >> u >> v >> w;
  47.         edge[i] = {u,v,w};
  48.     }
  49.    
  50.     int res = kruskal();

  51.     for (int i = 1;i <= n-1;i ++){
  52.         int id = path[i];
  53.         cout << edge[id].a << ' ' << edge[id].b << ' ' << edge[id].w << '\n';
  54.     }
  55.     cout << res << '\n';
  56.     return 0;
  57. }
复制代码


自己写的,没有按照你给的代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-9-7 21:18:23 | 显示全部楼层    本楼为最佳答案   
  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. #define IOS \
  6.     ios::sync_with_stdio(false); \
  7.     cin.tie(0); \
  8.     cout.tie(0)
  9. const int N = 1e5+5,M = 2e5+5;
  10. int n,m;
  11. int p[N],path[N];

  12. int find(int a){
  13.     if (p[a] != a) p[a] = find(p[a]);
  14.     return p[a];
  15. }

  16. struct Edge{
  17.     int a,b,w;// 需要对边排序,用结构体存储
  18.     bool operator< (const Edge& W) const{
  19.         return w < W.w;// 重载小于号
  20.     }
  21. }edge[M];

  22. int kruskal(){
  23.     sort(edge + 1,edge + m + 1);// 数组从下标为1开始存边
  24.     for (int i = 1; i <= n; i ++ ) p[i] = i;// 初始化并查集
  25.    
  26.     int res = 0,cnt = 0;// res存放最小生成树的边权之和,cnt存放最小生成树的边数
  27.     for (int i = 1;i <= m;i ++){
  28.         int a = edge[i].a,b = edge[i].b,w = edge[i].w;
  29.         a = find(a),b = find(b);
  30.         if (a != b){
  31.             p[a] = b;
  32.             res += w;
  33.             cnt ++;
  34.             path[cnt] = i;
  35.         }// n个点一共n-1条边
  36.         if (cnt == n-1) break;// 处理完提前退出
  37.     }
  38.     return res;
  39. }

  40. int main(){
  41.     IOS;
  42.    
  43.     cin >> n >> m;
  44.     int u,v,w;
  45.     for (int i = 1; i <= m; i ++ ){
  46.         cin >> u >> v >> w;
  47.         edge[i] = {u,v,w};
  48.     }
  49.    
  50.     int res = kruskal();

  51.     for (int i = 1;i <= n-1;i ++){
  52.         int id = path[i];
  53.         cout << edge[id].a << ' ' << edge[id].b << ' ' << edge[id].w << '\n';
  54.     }
  55.     cout << res << '\n';
  56.     return 0;
  57. }
复制代码


自己写的,没有按照你给的代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-26 15:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表