码迷,mamicode.com
首页 > 其他好文 > 详细

MST的回顾

时间:2015-10-05 22:03:15      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:

记得上一次看图论都是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 }

 

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

MST的回顾

标签:

原文地址:http://www.cnblogs.com/novioleo/p/4856275.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!