最小生成树(卡鲁斯卡尔)

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2896

最小生成树:n个顶点n-1条边

本题因为有50000个点,所以只能用Kuscal

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6. using namespace std;
  7. int n,m,tt;
  8. struct node
  9. {
  10. int x,y,w;
  11. }edge[200001];
  12. int bin[50002];
  13. void add(int u,int v,int w1)
  14. {
  15. edge[tt].x=u;
  16. edge[tt].y=v;
  17. edge[tt].w=w1;
  18. tt++;
  19. }
  20. int cmp(const void *a,const void *b)
  21. {
  22. return (*(struct node *)a).w-(*(struct node *)b).w;
  23. }
  24. int findx(int x)
  25. {
  26. int r=x;
  27. while(r!=bin[r])
  28. r=bin[r];
  29. int j,k;
  30. j=x;
  31. while(j!=r)
  32. {
  33. k=bin[j];
  34. bin[j]=r;
  35. j=k;
  36. }
  37. return r;
  38. }
  39. void merge(int fx,int fy)
  40. {
  41. // int fx=findx(x);  //节约时间
  42. //int fy=findx(y);  //节约时间
  43. if(fx!=fy)
  44. bin[fx]=fy;
  45. }
  46. void Kuscal()
  47. {
  48. int sum=0;
  49. int ll=1;//最小生成树n-1条边
  50. int i=0;
  51. while(ll<n)
  52. {
  53. if(findx(edge[i].x)!=findx(edge[i].y))
  54. {
  55. merge(edge[i].x,edge[i].y);
  56. sum=sum+edge[i].w;
  57. ll++;
  58. }
  59. i++;
  60. }
  61. printf("%d\n",sum);
  62. }
  63. int main()
  64. {
  65. int u,v,w1;
  66. while(scanf("%d%d",&n,&m)!=EOF)
  67. {
  68. tt=0;
  69. for(int i=1;i<=n;i++)
  70. bin[i]=i;
  71. while(m--)
  72. {
  73. scanf("%d%d%d",&u,&v,&w1);
  74. add(u,v,w1);
  75. }
  76. qsort(edge,tt,sizeof(edge[0]),cmp);
  77. Kuscal();
  78. }
  79. return 0;
  80. }

最小生成树(卡鲁斯卡尔),布布扣,bubuko.com

时间: 2024-10-27 07:46:19

最小生成树(卡鲁斯卡尔)的相关文章

贪心算法(Greedy Algorithm)之最小生成树 克鲁斯卡尔算法(Kruskal&amp;#39;s algorithm)

克鲁斯卡尔算法(Kruskal's algorithm)是两个经典的最小生成树算法的较为简单理解的一个.这里面充分体现了贪心算法的精髓.大致的流程能够用一个图来表示.这里的图的选择借用了Wikipedia上的那个.很清晰且直观. 首先第一步,我们有一张图,有若干点和边 例如以下图所看到的: 第一步我们要做的事情就是将全部的边的长度排序,用排序的结果作为我们选择边的根据.这里再次体现了贪心算法的思想.资源排序,对局部最优的资源进行选择. 排序完毕后,我们领先选择了边AD. 这样我们的图就变成了 第

hdu-1863畅通工程 最小生成树克鲁斯卡尔算法kruskal(并查集实现)

畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16994    Accepted Submission(s): 7134 Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出

hdu 1598 find the most comfortable road(枚举+卡鲁斯卡尔最小生成树)

find the most comfortable road Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3999    Accepted Submission(s): 1720 Problem Description XX 星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam Structure---超

POJ 3723 Conscription 最小生成树 克鲁斯卡尔算法变形

#include <cstdio> #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <cstdlib> #include <cmath> #include <set> #include <map> #include <vector> #include <cstri

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

Kruskal算法的过程: (1) 将全部边按照权值由小到大排序. (2) 按顺序(边权由小到大的顺序)考虑没条边,只要这条边和我们已经选择的边步构成圈,就保留这条边,否则放弃这条边.算法 成功选择(n-1)条边后,形成一个棵最小生成树,当然如果算法无法选择出(n-1)条边,则说明原图不连通. 图中的路径按照权值的大小的排序为 AF 1; BE 4; BD 5; BC 6; DC:10; BF 11; DF 14; AE 16; AB 17; EF 33; 算法的处理过程如下 先选A,F不在一个

图解最小生成树 - 克鲁斯卡尔(Kruskal)算法

我们在前面讲过的<克里姆算法>是以某个顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树的.同样的思路,我们也可以直接就以边为目标去构建,因为权值为边上,直接找最小权值的边来构建生成树也是很自然的想法,只不过构建时要考虑是否会形成环而已,此时我们就用到了图的存储结构中的边集数组结构,如图7-6-7 假设现在我们已经通过邻接矩阵得到了边集数组edges并按权值从小到大排列如上图. 下面我们对着程序和每一步循环的图示来看: 算法代码:(改编自<大话数据结构>) C++ Code 1

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

按照惯例,接下来是本篇目录: $1 什么是最小生成树? $2 什么是克鲁斯卡尔算法? $3 克鲁斯卡尔算法的例题 摘要:本片讲的是最小生成树中的玄学算法--克鲁斯卡尔算法,然后就没有然后了. $1 什么是最小生成树? •定义: 先引入一个定理:N个点用N-1条边连接成一个联通块,形成的图形只可能是树,没有别的可能: 根据这个定理,我们定义:在一个有N个点的图中,选出N-1条边出来,连接所有N个点,这N-1条边的边权之和最小的方案: •最小生成树之prim算法:   由于本蒟蒻还不会这个算法,所以

hduoj-1301 Jungle Roads(最小生成树-克鲁斯卡尔和普里姆求解)

普里姆求解: #include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<cstdlib> #include<algorithm> #include<string> #include<stack> #include<queue> #include<map> using namespace s

最小生成树 - 克鲁斯卡尔算法

从边考虑, 给一些输入,9 15 #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define MAXEDGE 100 #define MAXVEX 100 #define INFINITY 65535 using namespace std; typedef struct Edge{ int begin; int end; int weight; bool

最小生成树 - 克鲁斯卡尔 - 并查集 - 边稀疏 - O(E * logE)

#define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 100005 int p[N]; struct Edge { int s, e; int cost; }edge[N]; bool cmp(struct Edge a, struct Edge b) { return a.cost <