MST的回顾

记得上一次看图论都是5月份到6月份在准备比赛的时候的事了,最近在做一个pat的题,又遇见图论的题了,发现自己还是无法很灵活的来思考,故今天在http://wenku.baidu.com/link?url=xh_bpNdXCwUwRFqlFJNdmTil99yyTn3gaOkK5FSdGANE34hLoZhXIFj1Q8VYJHVfMxirWeuw8U3rmO2Vyg9j8P0Eflq-qjBN0_Zkub3xo-q 看了经典图论算法,顺便做个笔记方便以后自己复习

最小生成树

prim

点集合A,点集合B

集合A中初始情况下放置全部点

集合B中初始情况下没有点

从A中选择任意一个点放入B中

循环:

对B中所有点的所有在A中可用点进行遍历

找到最小值的点,累加这个值,并将该点从A放入B中

直至A中没有点,结束循环

我的代码比较麻烦,但是意思还是那个意思:

 1 #include"iostream"
 2
 3 #include"cstring"
 4
 5 #include"set"
 6
 7 using namespace std;
 8
 9
10
11 int main(){
12
13  //点到另一个点的权值
14
15  int map[101][101];
16
17  //有哪些点
18
19  set<int> pts;
20
21  memset(map,0,sizeof(map));
22
23
24
25
26
27  int n,x,y,weight;
28
29  cin>>n;
30
31  for(int i = 0;i < n;++i){
32
33   cin>>x>>y>>weight;
34
35   pts.insert(x);
36
37   pts.insert(y);
38
39   map[x][y] = weight;
40
41   map[y][x] = weight;
42
43  }
44
45
46
47  set<int> res;
48
49  res.insert(*(pts.begin()));
50
51  pts.erase(pts.begin());
52
53
54
55  int sum = 0;
56
57  while(!pts.empty()){
58
59   set<int>::iterator itA,itB;
60
61   int minPoint,minWeight = 0x7fffffff;
62
63   for(itA = res.begin();itA != res.end();++itA){
64
65    int pointA = *itA;
66
67    for(itB = pts.begin();itB != pts.end();++itB){
68
69     int pointB = *itB;
70
71     if(map[pointA][pointB] != 0 && map[pointA][pointB] <= minWeight){
72
73      minPoint = pointB;
74
75      minWeight = map[pointA][pointB];
76
77     }
78
79    }
80
81   }
82
83   sum += minWeight;
84
85   res.insert(minPoint);
86
87   pts.erase(minPoint);
88
89  }
90
91
92
93  cout<<sum<<endl;
94
95
96
97  return 0;
98
99 } 

测试数据如下:

输入

8

1 2 2

1 3 12

1 4 10

2 3 8

2 5 9

5 3 3

5 4 7

4 3 6

输出 19

kruskal:

排序所有权重

从小到大累加,如果对应的边导致累加过程中出现回路则跳过这条边

对于kruskal算法来说最麻烦的地方就是判断是否形成回路,这里会用到并查集的方式来解决问题:

并查集:

求取现在所有点的父节点。只要是同一个父节点就说明是处于同一个回路中。

  1 #include"iostream"
  2
  3 #include"algorithm"
  4
  5 #include"cstring"
  6
  7 using namespace std;
  8
  9 typedef struct edge{
 10
 11  int src;
 12
 13  int dst;
 14
 15  int weight;
 16
 17 }edge;
 18
 19 int comp(const void *a,const void *b){
 20
 21  edge x = *(edge*)a,y = *(edge*)b;
 22
 23  return x.weight - y.weight;
 24
 25 }
 26
 27 int UFS[101];
 28
 29 int find(int x){
 30
 31  if(UFS[x] != x)
 32
 33   UFS[x] = find(UFS[x]);
 34
 35  return UFS[x];
 36
 37 }
 38
 39 int main(){
 40
 41
 42
 43  int n,x,y,weight;
 44
 45  cin>>n;
 46
 47  edge* edges = new edge[n];
 48
 49  for(int i = 0;i < n;++i){
 50
 51   cin>>x>>y>>weight;
 52
 53   edges[i].src = x;
 54
 55   edges[i].dst = y;
 56
 57   edges[i].weight = weight;
 58
 59  }
 60
 61
 62
 63  qsort(edges,n,sizeof(edge),comp);
 64
 65  for(int i = 0;i < 101;++i)
 66
 67   UFS[i] = i;
 68
 69
 70
 71  int sum = 0;
 72
 73
 74
 75  for(int i = 0;i < n;++i){
 76
 77   edge temp = edges[i];
 78
 79   int p = find(temp.dst);
 80
 81   int q = find(temp.src);
 82
 83   if(p != q){
 84
 85
 86
 87    if(temp.dst > temp.src) //这里必须要对大小进行判断不然顺序会出错
 88
 89     UFS[temp.dst] = temp.src;
 90
 91    else UFS[temp.src] = temp.dst;
 92
 93
 94
 95    sum += temp.weight;
 96
 97   }
 98
 99  }
100
101
102
103  cout<<sum<<endl;
104
105
106
107  return 0;
108
109 }

当自己重新写一遍的时候才会发现问题所在。也希望大家能多多交流。

时间: 2024-11-06 22:48:54

MST的回顾的相关文章

【每日算法】图算法(遍历&amp;MST&amp;最短路径&amp;拓扑排序)

图有邻接矩阵和邻接表两种存储方法,邻接矩阵很简单,这里不讨论,下面我们先看看常用的邻接表表示方法. 邻接表常用表示方法 指针表示法 指针表示法一共需要两个结构体: struct ArcNode //定义边表结点 { int adjvex: //邻接点域 ArcNode* next; }; struct VertexNode //定义顶点表结点 { int vertex; ArcNode* firstedge; }; 每个节点对应一个VertexNode,其firstedge指向边表(与当前节点邻

Spring知识点回顾(01)

Spring知识点回顾(01) 一.依赖注入 1.声明Bean的注解 @Component @Service @Repository @Controller 2.注入Bean的注解 @Autowired @Inject @Resource 二.加载Bean 1.xml方式 - applicationcontext.xml : Beans, Bean, Component-Scan 2.注解方式 - @Configuration,@ComponentScan,@Bean 用@Configurati

Atitit.播放系统规划新版本 v4 q18 and 最近版本回顾

Atitit.播放系统规划新版本 v4  q18  and 最近版本回顾 1 版本12 (ing)4 1.1 无映射nas系统..4 1.2 图片简介搜刮其4 1.3 12.8. 电影图片增加png,bmp等格式支持,目前只有jpg方式95 1.4 12.9. 电影简介增加utf8编码支持,目前只有gbk编码方式95 1.5 12.10. 路径item俩端过滤空格,增强对路径 的容错处理95 1.6 不同分店的分类配置分离5 1.7 问题自动反馈支持5 1.8 规划h5本地缓存系列 5 1.9 

程序员之路--回顾2015,展望2016

一.前言 回顾2015年,有太多的事情,从暑假末的来北京找工作,到家里兄弟的结婚,再到自己喜欢的人也来到北京找工作,,,有太多的需要来回忆,来记录.今天就在此刻(2016年1月3日下午10:17)来简单的对2015年的自己进行总结,然后规划一下2016年的奋斗目标. 二.先谈谈工作 从暑假结束快要结束的时候,看看原来写的随笔,也就是2015年8月22日,和同学一起踏上开往北京的火车.用了一个月的时间找到了一份自己还觉得不错的工作.找工作那一个月里面每天吃饭.看书.面试.睡觉.这里想对将要找工作的

ACdream 1135 MST

MST Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Problem Description Given a connected, undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices together.  A single

poj1789 MST 读题生涯永不停歇

题目: 链接在此 1.图论刷刷乐#1的第一题,无奈看了好长时间题目还是看不懂= =,明知是最水的题目 2.搜懂题目后,比较裸的MST,但还是决定写个题解,虽然没什么可说的,只是来警戒自己,还是要努力读题,YY大法,这也是水平的一个体现! #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include &

linux习题回顾

linux习题回顾 1.1 创建一个压缩包/etc,我想让压缩包上面有个日期/时间. [[email protected] ~]# tar zcf /tmp/etc-$(date+%F).tar.gz /etc [[email protected] ~]# ls -l /tmp -rw-r--r--. 1 root root 9731838 Aug  3 19:15 etc-2017-08-03.tar.gz 1.2 已知/oldboy/test.txt文件内容为: oldboy xizi xi

面向对象【day07】:多态-面向对象使用场景--知识点回顾

本节内容 多态 面向对象使用场景 知识点回顾 一.多态 一.概述 多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作.简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针. 那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化:继承可以扩展已存在的代码模块(类):它们的目的都是为了--代码重用.而多态则是为了实现另一个目的--接口重用!多态的作用,就是为了

react回顾

读书就像盖房子,根基要正,刚开始要选一些文风简明的...react 小书 就不错. 创建组件(extends 或是 stateless) 父子组件之间的通信(super) 事件监听(event对象和this) 渲染列表(map) 状态提升(state) 挂载阶段声明周期 更新阶段生命周期(setState) 容器类组件(this.props.children) Proptypys验证 defaultProps 高阶组件(返回新的组件类) getChildContext(childContextT