在一个具有几个顶点的连通图G中,如果存在子图G'包含G中所有顶点和一部分边,且不形成回路,则称G'为图G的生成树,代价最小生成树则称为最小生成树。
许多应用问题都是一个求无向连通图的最小生成树问题。例如:要在n个城市铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同;另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。
算法为贪心思想,每次将距离最近的一个顶点入MST中,然后对剩余的顶点做松弛操作。MST算法可以使用有限队列来实现,使用二叉堆O(VlogV+ElogV),使用FIB-heapO(VlogV+E),但是使用优先队列的实现比较适合与稀疏图。稠密图只要维护一个数组存储每个点的距离即可效率为O(V*V+E).
下面代码为zoj_1586的解
稠密图:
#include <iostream> #include<stdio.h> #define DEBUG 1 using namespace std ; const int Max=0x7fffffff ; const int MaxSize=1001 ; int map[MaxSize][MaxSize], dis[MaxSize], cost[MaxSize] ; bool used[MaxSize] ; int n ; long long len ; void init( ) { int i ; for( i=0; i<MaxSize; ++i ) used[i] = false ; len = 0 ; } void Prim( ) { int Min, index, i, j ; for( i=1; i<=n; ++i ){ dis[i] = map[1][i] ; } used[1] = true ; for( i=1; i<n; ++i ){ Min = Max ; for( j=1; j<=n; ++j ){ if( !used[j] && Min>dis[j] ){ index = j ; Min = dis[j] ; } } used[index] = true ; len += dis[index] ; for( j=1; j<=n; ++j ){ if( !used[j] && dis[j]>map[index][j] ) dis[j] = map[index][j] ; } } } int main() { #if DEBUG freopen("e:\\zoj\\zoj_1586.txt","r",stdin) ; #endif int sets, i, j, distance ; scanf("%d", &sets ) ; while( sets-- ){ init( ) ; scanf("%d", &n ) ; for( i=1; i<=n; ++i ) scanf("%d", &cost[i] ) ; for( i=1; i<=n; ++i ){ for( j=1; j<=n; ++j ){ scanf("%d", &distance ) ; map[i][j] = distance+cost[i]+cost[j] ; } } Prim( ) ; printf("%lld\n", len ) ; } return 0 ; }
稀疏图:
#include<iostream> #include<string.h> #include<fstream> using namespace std; class node { public: int key,value; node() { key=-1; value=-1; } }; class priority_queue { public: const static int maxm=1005; node array[maxm]; int index[maxm]; int flag; priority_queue() { this->flag=0; } priority_queue(int flag) { this->flag=flag-1; } void heapify_MIN() { int n=flag/2+flag%2-1; for(int i=n;i>=0;i--) buildHeap_MIN(i,flag); } void buildHeap_MIN(int k,int m) { int j=2*k+1; if(j>m) return; if(j+1<=m&&array[j].value>array[j+1].value) j=j+1; if(array[k].value>array[j].value) { int a=array[k].key; int b=array[j].key; index[a]=j; index[b]=k; node temp=array[k]; array[k]=array[j]; array[j]=temp; buildHeap_MIN(j,m); } } node extract_MIN() { node res=array[0]; int a=array[0].key; int b=array[flag].key; index[a]=flag; index[b]=0; node temp=array[0]; array[0]=array[flag]; array[flag]=temp; this->flag--; buildHeap_MIN(0,flag); return res; } void decrease_key(int k,int key) { if(k==0&&key<array[k].value) { array[k].value=key; return; } if(array[k].value<=key) return; else { int n=k/2+k%2-1; if(array[n].value>key) { int a=array[k].key; int b=array[n].key; index[a]=n; index[b]=k; node temp=array[k]; array[k]=array[n]; array[n]=temp; decrease_key(n,key); } else { array[k].value=key; return; } } } }; int cases,n,dist; const int maxm=10000; int graphMatrix[1001][1001]; int favorate[1001]; int s[1001]; int path[1001]; int main() { /*ifstream txtfile; txtfile.open("e:\\zoj\\zoj_1586.txt"); if(!txtfile) { cerr<<"open error"<<endl; exit(1); } txtfile>>cases;*/ cin>>cases; while(cases--) { //txtfile>>n; cin>>n; for(int i=0;i<n;i++) { //txtfile>>favorate[i]; cin>>favorate[i]; } //memset(graphMatrix,0,sizeof(graphMatrix)); memset(s,0,sizeof(s)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) { //txtfile>>dist; cin>>dist; graphMatrix[i][j]=dist+favorate[i]+favorate[j]; } priority_queue q(n-1); for(int i=1;i<n;i++) { path[i]=0; s[i]=0; } path[0]=0; s[0]=1; for(int i=0;i<n-1;i++) { q.array[i].value=graphMatrix[0][i+1]; q.array[i].key=i+1; } for(int i=1;i<n;i++) { q.index[i]=i-1; } q.heapify_MIN(); int result=0; for(int i=1;i<n;i++) { node p=q.extract_MIN(); s[p.key]=1; result+=p.value; //cout<<p.key<<" "; for(int j=1;j<n;j++) { if(s[j]==0&&j!=p.key) { int index=q.index[j]; if(graphMatrix[p.key][j]<q.array[index].value) { q.decrease_key(index,graphMatrix[p.key][j]); path[j]=p.key; } } } } //cout<<endl; cout<<result<<endl; } return 0; }
发表评论
-
图的割点tarjan---zoj_1119
2011-10-24 23:00 1236http://acm.zju.edu.cn/on ... -
BFS与双向BFS---zoj_1505
2011-10-09 17:14 1647http://acm.zju.edu.c ... -
静态treap+线段树---zoj_2112
2011-09-29 23:06 1712http://acm.zju.edu ... -
NIM博弈游戏,SG函数---zoj_3084,zoj_2083
2011-09-23 23:00 1322Nim游戏是两个人进行的游戏有如下规则: ... -
多重背包--zoj_2156
2011-09-14 11:10 867首先介绍经典的三种背包问题,0-1背包,完全 ... -
模式串匹配---KMP
2011-08-31 20:49 1282朴素的的模式串匹配算法通常要在向前移动文本指针 ... -
八数码问题(A*&&双向BFS)---zoj_1217
2011-08-30 22:13 1672题目地址:http://acm.zju.edu.cn/onli ... -
ac自动机以及它上面的DFA
2011-08-08 23:04 2483AC自动机(Aho-Corasick)主要用 ... -
二分图最大匹配(匈牙利算法)--zoj1516,1525,2223
2011-07-20 22:36 1189二分图G(E,V)将点集合V分成两个部分L,R ... -
网络最大流(EK)---zoj_1734
2011-07-19 16:34 2136网络最大流是图论中的一个典型问题,为了精确的定 ... -
trie和前缀检查---zoj_2876
2011-07-13 23:03 870trie树是一种多叉树,广泛用于字典检索。如 ... -
位图bitmap
2011-07-13 21:08 916bitmap是一种广泛使用的数据结构,主要用在 ... -
LAC和RMQ的转化---zoj_3195
2011-07-12 22:35 1078我擦。。纠结了好久啊,从SF到TLE,先总结2 ... -
LAC的tarjan(离线)算法---zoj_1141
2011-07-08 17:52 1662LCA就不解释了,这里主要再次复习一下LC ... -
笛卡尔树以及treap---zoj_2243
2011-07-07 15:52 2847zoj_2243笛卡 ... -
线段染色,矩形切割,离散化---zoj_2301,zoj_1128
2011-06-24 22:32 1369染色问题:在一维坐标轴上(最右端为M),有N ... -
线段树---zoj_1610
2011-06-22 21:06 755线段树是一种二叉树的拓展,在线段树每个节点中 ... -
快速排序(qsort)
2011-06-16 17:03 782快速排序是一种高效的非稳定排序,它的基本思路 ... -
斐波那契散列
2011-06-16 16:38 3083斐波那契散列法其实是一种特殊的乘法散列,先来看乘法 ... -
强连通分支(scc)---tarjan
2011-06-15 16:17 1285本文大量 ...
相关推荐
最小生成树_Prim算法实现C++ 最小生成树_Prim算法实现C++ 最小生成树_Prim算法实现C++
问题描述:给定一个地区的n个城市间的距离网,用Prim算法或Kruskal算法建立最小生成树,并计算得到的最小生成树的代价。基本要求:1、城市间的距离网采用邻接矩阵表示,邻接矩阵的存储结构定义采用课本中给出的定义...
代码 最小生成树Prim算法代码代码 最小生成树Prim算法代码代码 最小生成树Prim算法代码代码 最小生成树Prim算法代码代码 最小生成树Prim算法代码代码 最小生成树Prim算法代码代码 最小生成树Prim算法代码代码 最小...
使用Prim算法编写的最小生成树(C语言),为更好地学习数据结构
最小生成树之prim
利用c++编程实现,最小生成树的Prim算法,
Prim最小生成树Prim最小生成树Prim最小生成树
图论- 生成树- 最小生成树- Prim.rar
最小生成树prim最小生成树prim最小生成树prim最小生成树prim
用matlab语言编写的最小生成树的prim算法的通用源程序。
实现构造最小生成树的Prim算法
05最小生成树_Prim.c
prim算法 Kruskal算法分别实现最小生成树
图论算法:最小生成树——Prim算法和Kruskal算法C 实现
最小生成树_Prim算法实现C++.doc
最小生成树的Prim算法 /2,Prim算法的描述:// 假如N=(V,{E})是连通网,TE是N上最小生成树中边得集合。算法从U={u0}(u0是V中的元素),TE={}开始,重复执行下述操作:// 在所有u属于U,v属于V-U的边(u,v)属于E...
最小生成树算法是基于贪心的思想得到的。包括Kruskal算法和Prim算法
用字符文件提供数据建立连通带权网络邻接矩阵存储¬¬结构。编写程序,用Prim算法求一棵最小生成树。要求输出最小生成树的各条边(用顶点无序偶表示)、各条边上的权值、最小生成树所有边上的权值之和。
普里姆算法通过寻找无向图中权值最小的边,并且将其组合成最小生成树,也就是图的相对最短路径,同时将最小生成树以点集的形式输出,便于观察
最小生成树,使用PRIM方法生成最小生成树。