SDUT 2144 图结构练习——最小生成树

题目链接 :http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2144

图结构练习——最小生成树

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

有n个城市,其中有些城市之间可以修建公路,修建不同的公路费用是不同的。现在我们想知道,最少花多少钱修公路可以将所有的城市连在一起,使在任意一城市出发,可以到达其他任意的城市。

输入

输入包含多组数据,格式如下。

第一行包括两个整数n m,代表城市个数和可以修建的公路个数。(n <= 100, m <=10000)

剩下m行每行3个正整数a b c,代表城市a 和城市b之间可以修建一条公路,代价为c。

输出

每组输出占一行,仅输出最小花费。

示例输入

3 2
1 2 1
1 3 1
1 0

示例输出

2
0

提示

来源

赵利强

示例程序

由于n*n和m的大小差不多,所以这题可以选择Prime算法(n*n<m),也可以选择Kruskal(n*n>m)

先是Prime算法,代码如下

view plaincopyprint如果您复制代码时出现行号,请点击左边的“view
plain”后再复制

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #define inf 99999999
  5. using namespace std;
  6. int main()
  7. {
  8. int n, m;
  9. while(~scanf("%d %d", &n, &m))
  10. {
  11. int a[100+5][100+5];
  12. for(int i=1;i<=n;i++)
     //初始化
  13. for(int j=1;j<=n;j++)
  14. if(i==j) a[i][j]=0;
  15. else a[i][j]=inf;
  16. while(m--)
  17. {
  18. int u, v, w;
  19. scanf("%d %d %d", &u, &v, &w);
  20. if(a[u][v]>w) a[u][v]=a[v][u]=w;
     //注意这里是无向图,并且可能存在重复的u、v信息
  21. }
  22. int dis[100+5], sum=0;
  23. bool vis[100+5];
  24. for(int i=1;i<=n;i++)
  25. dis[i]=a[1][i];
  26. memset(vis,0,sizeof(vis));
     //设置标记数组vis
  27. vis[1]=1;
  28. for(int i=1;i<n;i++)
  29. {
  30. int min=inf, pos=inf;
  31. for(int j=1;j<=n;j++)
  32. if(!vis[j]&&dis[j]<min)
     //查找并记录最小值及其下标,表明此值已经“明确”为最短(意思是没有其他路径可以让它变得更短,也就是无法再进行“松弛”)
  33. {
  34. min=dis[j];
  35. pos=j;
  36. }
  37. if(min>=inf) break;
     //如果所有值都已“明确”为最短,结束循环
  38. sum+=min;
  39. vis[pos]=1;
  40. for(int j=1;j<=n;j++)
  41. if(!vis[j]&&dis[j]>a[pos][j])
     //使用该最短路径“松弛”其他路径
  42. dis[j]=a[pos][j];
  43. }
  44. printf("%d\n", sum);
  45. }
  46. return 0;
  47. }

再是Kruskal:

view plaincopyprint如果您复制代码时出现行号,请点击左边的“view
plain”后再复制

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. int pre[100+5];
  6. struct node
  7. {
  8. int u, v, w;
  9. }boy[10000+5];
  10. bool cmp(node a, node b)
  11. {
  12. return a.w<b.w;
  13. }
  14. int root(int a)
     \\查找
  15. {
  16. int x=a;
  17. while(x!=pre[x])
  18. {
  19. x=pre[x];
  20. }
  21. while(a!=x)
     //路径压缩
  22. {
  23. pre[a]=x;
  24. a=pre[a];
  25. }
  26. return x;
  27. }
  28. int main()
  29. {
  30. int m, n;
  31. while(~scanf("%d %d", &n, &m))
  32. {
  33. for(int i=1;i<=n;i++)
  34. pre[i]=i;
  35. for(int i=0;i<m;i++)
  36. scanf("%d %d %d", &boy[i].u, &boy[i].v, &boy[i].w);
  37. sort(boy,boy+m,cmp);  //对结构体按路径花费进行升序排序
  38. int ans=0, cnt=0;
  39. for(int i=0;i<m;i++)
  40. {
  41. if(root(boy[i].u)!=root(boy[i].v))
     //合并
  42. {
  43. pre[root(boy[i].u)]=root(boy[i].v);
  44. ans+=boy[i].w;
  45. cnt++;
  46. }
  47. if(cnt>=n-1) break;
     //只需再联通n-1个节点即可保证全部联通
  48. }
  49. printf("%d\n", ans);
  50. }
  51. return 0;
  52. }

十一点半了快,睡觉了,明天继续,晚安世界

时间: 2024-08-29 01:55:33

SDUT 2144 图结构练习——最小生成树的相关文章

图结构练习——最小生成树

图结构练习--最小生成树 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 有n个城市,其中有些城市之间可以修建公路,修建不同的公路费用是不同的.现在我们想知道,最少花多少钱修公路可以将所有的城市连在一起,使在任意一城市出发,可以到达其他任意的城市. 输入 输入包含多组数据,格式如下. 第一行包括两个整数n m,代表城市个数和可以修建的公路个数.(n<=100) 剩下m行每行3个正整数a b c,代表城市a 和城市b之间可以修建

SDUT 2139 图结构练习——BFS——从起始点到目标点的最短步数(BFS + vector)

图结构练习--BFS--从起始点到目标点的最短步数 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 在古老的魔兽传说中,有两个军团,一个叫天灾,一个叫近卫.在他们所在的地域,有n个隘口,编号为1..n,某些隘口之间是有通道连接的.其中近卫军团在1号隘口,天灾军团在n号隘口.某一天,天灾军团的领袖巫妖王决定派兵攻打近卫军团,天灾军团的部队如此庞大,甚至可以填江过河.但是巫妖王不想付出不必要的代价,他想知道在不修建任何通道的前提下

一步一步写算法(之图结构)

原文:一步一步写算法(之图结构) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 图是数据结构里面的重要一章.通过图,我们可以判断两个点之间是不是具有连通性:通过图,我们还可以计算两个点之间的最小距离是多少:通过图,我们还可以根据不同的要求,寻找不同的合适路径.当然,有的时候为了计算的需要,我们还需要从图中抽象出最小生成树,这样在遍历计算的时候就不需要持续判断是不是遇到了循环节点.当然,这所有的一切都是从图的表示开始的. 1)矩阵表示 矩

图结构模板

大量图结构模板,可能会有帮助 #include<bits/stdc++.h>#define MAXN 100000#define D 10#define MAXM 10000010using std::cin;using std::cout;using std::endl;int m, n;//m为边数,n为点数//图的存储 //邻接矩阵int a[5010][5010];void init() { cin >> n >> m; for (int i = 1; i &l

图-结构

邻接矩阵 适用于小型的图,对于稀疏图很浪费,可用二维数组实现 邻接表 适用于稀疏图,可用vector实现 求最小生成树 利用 Kruska 算法,可以直接保存边 u,v,w,以边的编号为索引 利用 prim 算法,需要每次取得最小的顶点,类似与 Dijkstra 算法,可以用邻接矩阵完成 求最短路径 Floyd 正权边,三重循环,首先枚举k,中间点 Dijkstra 从未使用的点中找一个距离最小的点,可以用邻接矩阵实现O(V^2),也可以用邻接表实现,用优先队列保存每个点到源点的最小路径长度和编

图结构练习——判断给定图是否存在合法拓扑序列

图结构练习——判断给定图是否存在合法拓扑序列 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个有向图,判断该有向图是否存在一个合法的拓扑序列. 输入 输入包含多组,每组格式如下. 第一行包含两个整数n,m,分别代表该有向图的顶点数和边数.(n<=10) 后面m行每行两个整数a b,表示从a到b有一条有向边. 输出 若给定有向图存在合法拓扑序列,则输出YES:否则输出NO. 示例输入 1 0 2 2 1 2 2 1 示例输出 YES NO #inc

图结构练习——判断给定图是否存在合法拓扑序列(sdutoj)

#include<stdio.h>#include<string.h>int d[15],map[15][15],vis[15];int main(){    int i,j,k,f,n,m,u,v;    while(~scanf("%d%d",&n,&m))    {        memset(d,0,sizeof(d));        memset(map,0,sizeof(map));        memset(vis,0,size

C# 图结构操作

仿造<<Java常用算法手册>>里面对的算法,使用C#实现了一遍. 理论知识我就不讲解了,在这本书里面已经写的非常完美! 代码如何下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 图结构 { public class GraphMatrix { public static in

图结构练习——BFS——从起始点到目标点的最短步数(邻接表+BFS)

图练习-BFS-从起点到目标点的最短步数 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 在古老的魔兽传说中,有两个军团,一个叫天灾,一个叫近卫.在他们所在的地域,有n个隘口,编号为1..n,某些隘口之间是有通道连接的.其中近卫军团在1号隘口,天灾军团在n号隘口.某一天,天灾军团的领袖巫妖王决定派兵攻打近卫军团,天灾军团的部队如此庞大,甚至可以填江过河.但是巫妖王不想付出不必要的代价,他想知道在不修建任何通道的前提下,部队是否