N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。

输入

  1. 1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)
  2. 2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N1 <= W <= 10000)

输出

  1. 输出最小生成树的所有边的权值之和。

输入样例

  1. 9 14
  2. 1 2 4
  3. 2 3 8
  4. 3 4 7
  5. 4 5 9
  6. 5 6 10
  7. 6 7 2
  8. 7 8 1
  9. 8 9 7
  10. 2 8 11
  11. 3 9 2
  12. 7 9 6
  13. 3 6 4
  14. 4 6 14
  15. 1 8 8

输出样例

  1. 37
    解:Kruskal算法(排序后添加边)的两种实现(时间消耗差不多):
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. typedef struct Graph
  6. {
  7. int s,e,w;
  8. }graph;
  9.  
  10. int cmp(const void *a,const void *b)
  11. {
  12. return (*(graph *)a).w>(*(graph *)b).w?:-;
  13. }
  14.  
  15. graph p[];
  16. int vis[];
  17.  
  18. int main()
  19. {
  20. int n,m;
  21. while(scanf_s("%d%d",&n,&m)!=EOF)
  22. {
  23. int i,j,ans=;
  24. memset(vis,,n);
  25. for(i=;i<m;i++) scanf_s("%d%d%d",&p[i].s,&p[i].e,&p[i].w);
  26. qsort(p,m,sizeof(graph),cmp);
  27. vis[p[].s]=;
  28. vis[p[].e]=;
  29. ans+=p[].w;
  30. for(i=;i<n-;i++)
  31. {
  32. for(j=;j<m;j++)
  33. {
  34. if((vis[p[j].s]==&&vis[p[j].e]==)||(vis[p[j].s]&&vis[p[j].e]))
  35. continue;
  36. else
  37. {
  38. vis[p[j].s]=;
  39. vis[p[j].e]=;
  40. ans+=p[j].w;
  41. break;
  42. }
  43. }
  44. }
  45. printf("%d\n",ans);
  46. }
  47. return ;
  48. }
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<malloc.h>
  4.  
  5. typedef struct GRAPH
  6. {
  7. int s, e, w;
  8. }graph;
  9.  
  10. int cmp(const void *a, const void *b)
  11. {
  12. return ((graph *)a)->w > ((graph *)b)->w ? : -;
  13. }
  14.  
  15. graph p[];
  16. int *vis[];
  17.  
  18. int main()
  19. {
  20. int n, m;
  21. while (scanf_s("%d%d", &n, &m) != EOF)
  22. {
  23. int ans = ;
  24. for (int i = ; i < m; ++i) scanf_s("%d%d%d", &p[i].s, &p[i].e, &p[i].w);
  25. qsort(p, m, sizeof(graph), cmp);
  26. for (int i = , j = ; i < m; ++i)
  27. {
  28. int *tmp = (int *)malloc(sizeof(int));
  29. if (vis[p[i].e] == NULL)
  30. {
  31. if (vis[p[i].s] == NULL)
  32. {
  33. *tmp = j++;
  34. vis[p[i].e] = vis[p[i].s] = tmp;
  35. }
  36. else
  37. {
  38. vis[p[i].e] = vis[p[i].s];
  39. free(tmp);
  40. }
  41. }
  42. else if (vis[p[i].s] == NULL)
  43. {
  44. vis[p[i].s] = vis[p[i].e];
  45. free(tmp);
  46. }
  47. else
  48. {
  49. int *a, *b;
  50. for (a = vis[p[i].s]; *a > ; a = *a);
  51. for (b = vis[p[i].e]; *b > ; b = *b);
  52. if (*a == *b)
  53. {
  54. free(tmp);
  55. continue;
  56. }
  57. else
  58. {
  59. *tmp = *a;
  60. *b = *a = tmp;
  61. }
  62. }
  63. ans += p[i].w;
  64. }
  65. printf("%d\n", ans);
  66. }
  67. }

Prim算法(排序后添加点)(写的不好,时间消耗比上面的长):

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. #include <string.h>
  4.  
  5. #define MIN(a,b) (pt[a]->pr<pt[b]->pr?a:b)
  6.  
  7. typedef struct POINT
  8. {
  9. struct POINT *p;
  10. int ed,pr;
  11. }point;
  12.  
  13. point *pt[];
  14. int vis[][];
  15. int main()
  16. {
  17. int n, m;
  18. while (scanf_s("%d%d", &n, &m) != EOF)
  19. {
  20. int ans = ;
  21. while (m--)
  22. {
  23. int a, b, c;
  24. scanf_s("%d%d%d", &a, &b, &c);
  25. point *tmp1 = (point *)malloc(sizeof(point)), *tmp2 = (point *)malloc(sizeof(point));
  26. tmp1->ed = b;
  27. tmp2->ed = a;
  28. tmp1->pr = tmp2->pr = c;
  29. if (pt[a] == NULL|| tmp1->pr < pt[a]->pr)
  30. {
  31. tmp1->p = pt[a];
  32. pt[a] = tmp1;
  33. }
  34. else for (point *tmp0 = pt[a], *tmp = pt[a]; tmp0 != NULL; tmp = tmp->p)
  35. {
  36. if (tmp == NULL||tmp1->pr < tmp->pr)
  37. {
  38. tmp1->p = tmp0->p;
  39. tmp0->p = tmp1;
  40. break;
  41. }
  42. tmp0 = tmp;
  43. }
  44. if (pt[b] == NULL || tmp2->pr < pt[b]->pr)
  45. {
  46. tmp2->p = pt[b];
  47. pt[b] = tmp2;
  48. }
  49. else for (point *tmp0 = pt[a], *tmp = pt[b]; tmp0 != NULL; tmp = tmp->p)
  50. {
  51. if (tmp == NULL || tmp2->pr < tmp->pr)
  52. {
  53. tmp2->p = tmp0->p;
  54. tmp0->p = tmp2;
  55. break;
  56. }
  57. tmp0 = tmp;
  58. }
  59. }
  60. vis[][] = ;
  61. vis[][] = ;
  62. for (int i = ; i < n; i++)
  63. {
  64. int tmp = ;
  65. for (int j = ; j <= i; j++)
  66. {
  67. if (pt[vis[][j]] == NULL) continue;
  68. else if(vis[][pt[vis[][j]]->ed]!=)
  69. {
  70. if ( == tmp) tmp = vis[][j];
  71. else tmp = MIN(tmp, vis[][j]);
  72. }
  73. else
  74. {
  75. pt[vis[][j]] = pt[vis[][j]]->p;
  76. j--;
  77. }
  78. }
  79. vis[][i+] = pt[tmp]->ed;
  80. vis[][pt[tmp]->ed] = ;
  81. ans += pt[tmp]->pr;
  82. pt[tmp] = pt[tmp]->p;
  83. }
  84. printf("%d\n", ans);
  85. }
  86. }

(图论)51NOD 1212 无向图最小生成树的更多相关文章

  1. 51Nod 1212 无向图最小生成树 (路径压缩)

    N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树.   Input 第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量.(2 <= N <= 1000, 1 &l ...

  2. 51Nod 1212无向图最小生成树

    prim #include<stdio.h> #include<string.h> #define inf 0x3f3f3f3f ][]; ],lowc[]; ],int n) ...

  3. 51nod 1212 无向图最小生成树(Kruskal模版题)

    N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树.   Input 第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量.(2 <= N <= 1000, 1 &l ...

  4. 51 nod 1212 无向图最小生成树(Kruckal算法/Prime算法图解)

    1212 无向图最小生成树 N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树. 收起 输入 第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量.(2 <= N < ...

  5. 51 nod 1212 无向图最小生成树

    http://www.51nod.com/Challenge/Problem.html#problemId=1212 代码 #include<bits/stdc++.h> using na ...

  6. 51Nod-1212 无向图最小生成树

    51Nod: 1212 无向图最小生成树. link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1212 1212  ...

  7. 51nod1212无向图最小生成树

    1212 无向图最小生成树 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树.   Inpu ...

  8. 无向图最小生成树(prim算法)

    普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小.该算法于1930年由捷 ...

  9. [matlab] 22.matlab图论实例 最短路问题与最小生成树 (转载)

    最短路问题之 Floyd 某公司在六个城市 c1c1,c2c2,….,c6c6 中有分公司,从 cici 到 cjcj 的直接航程票价记在下述矩阵的 (ii,jj) 位置上. (∞∞表示无直接航路), ...

随机推荐

  1. 编译.net .net Core程序 代码,仅做备份

    //创建一个ProcessStartInfo对象 使用系统shell 指定命令和参数 设置标准输出 //编译.net core项目 var psi = new ProcessStartInfo(&qu ...

  2. POJ 3230 【DP】

    题意: 某货旅行,在n个城市呆m天. 给出从第i个城市到第j个城市的路费,或者留在某个城市的生活费. 给出在第i天在第j个城市的收益. 可以在城市之间任意穿梭逗留没有其他特殊要求. 求收益最大是多少. ...

  3. Java开发笔记(一百)线程同步synchronized

    多个线程一起办事固然能够加快处理速度,但是也带来一个问题:两个线程同时争抢某个资源时该怎么办?看来资源共享的另一面便是资源冲突,正所谓鱼与熊掌不可兼得,系统岂能让多线程这项技术专占好处?果然是有利必有 ...

  4. Java数组操作方法收集(快速判断某个值在这个数组中)

    Java数组操作最高效的方式是循环取值,如果转换成集合那么就会分配内存,效率不如前者,但是方法多,需要在性能调优上去权衡.切记:数组是数组,集合是集合. 下面是收集最常用的数组转成集合的操作方法: i ...

  5. 信号量学习 & 共享内存同步

    刚刚这篇文章学习了共享内存:http://www.cnblogs.com/charlesblc/p/6142139.html 里面也提到了共享内存,自己不进行同步,需要其他手段比如信号量来进行.那么现 ...

  6. [转]linux下tar.gz、tar、bz2、zip等解压缩、压缩命令小结

    原文:http://www.jb51.net/LINUXjishu/43356.html ------------------------------------------------------- ...

  7. Ansible 详细用法说明(二)

    setup:获取指定主机的facts. ===================================facts就是变量,内建变量 .每个主机的各种信息,cpu颗数.内存大小等.会存在fact ...

  8. [Bash] Move and Copy Files and Folders with Bash

    In this lesson we’ll learn how to move and rename files (mv) and copy (cp) them. Move index.html to ...

  9. [Angular] Expose Angular Component Logic Using State Reducers

    A component author has no way of knowing which state changes a consumer will want to override, but s ...

  10. Office EXCEL 表格如何设置某个单元格是选择项,如何设置一级下拉菜单

    1 比如我要在C这一列都做成下拉菜单,则我选中这一列的第一个单元格,然后点击数据-有效性,然后把允许改成"序列",在来源中输入每一项(用逗号隔开),比如我一共要做四个下拉菜单选项, ...