对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树

普里姆算法是以其中某一顶点为起点逐步寻找各个顶点上最小权值的边来构建最小生成树。

其中运用到了回溯,贪心的思想。

----------2018年5月24日补:

  #begin

    根据定义我们可知,求一个图的最小生成树的时候,一定会将所有的点都连接起来,也就是说,我们从任何一个点出发都可以得到这个图的最小生成树,那么我这里暂定从0出发,寻找到和0相连的点中最小的权值,作为连接0这一个点的边(如果有相同的最小权值,则视要求处理),将0这一个点设置为不可访问,同时保存此时的连接点,将求到的这一个点做和0一样相同的处理...处理出n个点就可以求得这个图的最小生成树了(如果不能处理出n个点,那么此图的最小生成树也就不存在)。

  #end

废话少说,直接上题吧!这些东西多练就好!

一、最小生成树:

题目描述
求一个连通无向图的最小生成树的代价(图边权值为正整数)。

输入
第 一行是一个整数N(1<=N<=20),表示有多少个图需要计算。以下有N个图,第i图的第一行是一个整数M(1<=M& lt;=50),表示图的顶点数,第i图的第2行至1+M行为一个M*M的二维矩阵,其元素ai,j表示图的i顶点和j顶点的连接情况,如果 ai,j=0,表示i顶点和j顶点不相连;如果ai,j>0,表示i顶点和j顶点的连接权值。

输出
每个用例,用一行输出对应图的最小生成树的代价。

样例输入
1
6
0 6 1 5 0 0
6 0 5 0 3 0
1 5 0 5 6 4
5 0 5 0 0 2
0 3 6 0 0 6
0 0 4 2 6 0

样例输出

15

//Asimple
#include <stdio.h>
#include <iostream>
#include <string.h>using namespace std;
#define INF 0xffffff
const int maxn = 55;
int G[maxn][maxn];//建图
int T, n;int prim()
{int Min, sum = 0;int adv[maxn]; //保存定点下标int lowc[maxn]; //保存权值adv[0] = lowc[0] = 0 ;//初始化for(int i=1; i<n; i++){lowc[i] = G[0][i];//先放入 第0行 的所有权值adv[i] = 0 ;}//构建过程for(int i=1; i<n; i++){Min = INF ;int j = 1 ;int k = 0 ;while( j < n ){if( lowc[j]!=0 && lowc[j]<Min){Min = lowc[j] ;k = j ;}j ++ ;}sum += G[adv[k]][k] ;//计算最小权值//printf("%d,%d",adv[k],k);//打印节点lowc[k] = 0 ;//逐行遍历接下来的k个顶点for(int l=1; l<n; l++){if( lowc[l]!=0 && G[k][l] < lowc[l] ){lowc[l] = G[k][l] ;adv[l] = k ;}}}return sum ;
}int main()
{cin >> T ;while( T -- ){cin >> n ;for(int i=0; i<n; i++)for(int j=0; j<n; j++){cin >> G[i][j];if( G[i][j] == 0 && i!=j )G[i][j] = INF ;}cout << prim() << endl ;}return 0;
}

二、判断最小生成树是否唯一

题目描述

给出一个连通无向图,请判断其最小生成树是否是唯一的。

定义1(生成树):给出一个连通无向图G=(V,E),G的一颗生成树被标记为T=(V,E),则具有以下性质:

1)V'=V;

2)T是连通无回路的。

定义2(最小生成树):给出一个边带权的连通无向图G=(V,E),G 的最小生成树T=(v,E)是具有最小总耗费的生成树。T的总耗费表示E' 中所有边的权值的和。

输入

第 一行给出一个整数t(1<=t<=20),表示测试用例数,每个测试用例表示一个图,测试用例的第一行给出两个整数n,m(1<=n<=100),分别表 示顶点和边的数目,后面的m行每行是一个三元组(xi,yi,wi),表示xi和yi通过权值为wi的边相连。任意两个节点间至多只有一条边相连。

输出

对于每个测试用例,如果MST是唯一的,输出其总耗费;否则输出字符串'Not Unique!'.

样例输入
2
3 3
1 2 1
2 3 2
3 1 3
4 4
1 2 2
2 3 2
3 4 2
4 1 2

样例输出

3

Not Unique!

#include <stdio.h>
#include <iostream>
#include <string.h>using namespace std;
#define INF 0xffffff
const int maxn = 55;
int G[maxn][maxn];//建图
int T, n, m, x, y, num;void prim()
{int Min, sum = 0;int adv[maxn]; //保存定点下标int lowc[maxn]; //保存权值bool flag = false ;adv[0] = lowc[0] = 0 ;//初始化for(int i=1; i<n; i++){lowc[i] = G[0][i];//先放入 第0行 的所有权值adv[i] = 0 ;}//构建过程for(int i=1; i<n; i++){Min = INF ;int j = 1 ;int k = 0 ;while( j < n ){if( lowc[j]!=0 && lowc[j]<=Min){if( lowc[j] == Min ) flag = true ;Min = lowc[j] ;k = j ;}j ++ ;}sum += G[adv[k]][k] ;//计算最小权值lowc[k] = 0 ;//逐行遍历接下来的k个顶点for(int l=1; l<n; l++){if( lowc[l]!=0 && G[k][l] < lowc[l] ){lowc[l] = G[k][l] ;adv[l] = k ;}}}if( flag ) cout << "Not Unique!" << endl ;else cout << sum << endl ;
}int main()
{cin >> T ;while( T -- ){cin >> n >> m ;for(int i=0; i<n; i++)for(int j=0; j<n; j++){if( i == j ) G[i][j] = 0 ;else G[i][j] = INF ;}for(int i=0; i<m; i++){cin >> x >> y >> num ;G[x-1][y-1] = num ;G[y-1][x-1] = num ;}prim();}return 0;
}

2018年4月1日更正:

上面的代码过不了  POJ 1679。谢谢指点~~   今天更改了下自己的程序。

18390068 Asimple 1679 Accepted 312K 16MS C++ 1483B 2018-04-01 20:08:48
//Asimple
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
using namespace std;
#define INF 0xffffff
typedef long long ll ;
const int maxn = 100+5;
int n, T, num, cnt, x, y, t, m, w;
int Map[maxn][maxn];void prim() {int lowc[maxn];for(int i=1; i<=n; i++) lowc[i] = Map[1][i];int sum = 0;bool flag = false;for(int l=1; l<n; l++) {int Min = INF;int k = 0;for(int j=2; j<=n; j++) {if( lowc[j]!=0 && Min > lowc[j] ) {k = j;Min = lowc[j];}}if( Min == INF ) break; sum += Min;int cnt = 0;for(int i=1; i<=n; i++)if( Map[k][i] == lowc[k] )cnt ++;if( cnt > 1 ) {flag = true;break;}lowc[k] = 0;for(int i=2; i<=n; i++) {if( lowc[i] > Map[k][i] ) {lowc[i] = Map[k][i];}}}if( flag ) cout << "Not Unique!" << endl;else cout << sum << endl;
}void input() {ios_base::sync_with_stdio(false);cin >> T;while( T -- ) {cin >> n >> m;for(int i=1; i<=n; i++) {for(int j=1; j<=n; j++) {Map[i][j] = i==j?0:INF;}}while( m -- ) {cin >> x >> y >> w;Map[x][y] = min(Map[x][y], w);Map[y][x] = Map[x][y];}prim();}
}int main() {input();return 0;
}

转载于:https://www.cnblogs.com/Asimple/p/5551129.html

ACM第四站————最小生成树(普里姆算法)相关推荐

  1. 最小生成树(普里姆算法【Prim】与克鲁斯卡尔算法【Kruskal】)

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  2. 最小生成树——普里姆算法和克鲁斯卡尔算法

    最小生成树 用来解决工程中的代价问题. 一:普里姆算法 具体代码用C语言实现如下: typedef int VRType;typedef char InfoType;#define MAX_NAME ...

  3. 最小生成树 普里姆算法

    题目来源  POJ2349 在介绍什么是最小生成树之前先介绍什么是加权图 在之前已经默认了解了无向图(并查集)以及有向无环图(拓扑排序),那么最小生成树可以理解是一个加权的无向图,那么我们要坐的就是在 ...

  4. (数据结构)图的最小生成树 普里姆算法(Prim)

    假设要在n个城市之间建立通信联络网,每两个城市之间建立线路都需要花费不同大小的经费,则连通n个城市只需要n-1个条线路,最小生成树解决的问题就是:如何在最节省经费的前提下建立这个通信网 也可以理解为: ...

  5. 学懂最小生成树(普里姆算法)

    最小生成树,初学者可能会学的感觉云里雾里,不要怕,小编带大家搞懂它! 目录 一.概念介绍 二.实现原理 三.代码实现 一.概念介绍 最小生成树就是在一个图中找到能过一次性穿过所有顶点的最小路径. 上图 ...

  6. 最小生成树普里姆算法c语言代码,普里姆算法生成最小生成树-C语言描述.doc

    PAGE JIN JINGCHU UNIVERSITY OF TECHNOLOGY <数据结构(C语言描述)> 课程设计 学 院 计算机工程学院 班 级 12级软件技术1班 学 号 201 ...

  7. USACO 3.1 Agri-Net 最短网络 (最小生成树)(普里姆算法)

    题意 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助.约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场.为了用最 ...

  8. 四、最小生成树——普里姆(Prim)算法

    一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边,那么我们把构造连通图网的最小代价生成树称为最小生成树(就是n个顶点,用n-1条边全部连接起来,并且使得权 ...

  9. 最小生成树普里姆算法Prim

    目录 前言 一.Prim算法的基本思路 二.代码实现 总结 前言   无论是什么程序都要和数据打交道,一个好的程序员会选择更优的数据结构来更好的解决问题,因此数据结构的重要性不言而喻.数据结构的学习本 ...

  10. prim算法(普里姆算法)详解

    prim算法(普里姆算法)详解 了解了什么是最小生成树后,本节为您讲解如何用普里姆(prim)算法查找连通网(带权的连通图)中的最小生成树. 普里姆算法查找最小生成树的过程,采用了贪心算法的思想.对于 ...

最新文章

  1. CveService.java
  2. BZOJ1444: [Jsoi2009]有趣的游戏(Trie图,矩乘)
  3. boost::math::nonfinite_num_facets用法的测试程序
  4. Nginx笔记-处女篇
  5. 编译内核_将驱动编译进内核(Kernel)的步骤记录
  6. java保存图书每日的交易记录
  7. Bug提交规范及注意事项
  8. 客户端程序调用zookeeper报len4807928异常
  9. HDU1230 火星A+B【进制】
  10. MySql - 事务 | 锁
  11. 虚幻3和虚幻4_虚幻的非会议
  12. 如何用计算机算电路,如何利用基础门电路进行加法计算和触发器
  13. 程序员博客是否应该晒代码(由摄影而感)
  14. 解决 注册谷 歌 邮 箱 gmail 手机号无法用于验证
  15. 【JS Web 前端知识库】6.说一说BFC
  16. 人工智能在集装箱识别中应用
  17. 静态页面和动态页面中的静态和动态到底指的是什么
  18. %02d得意思是什么?
  19. switch更新找不到服务器,任天堂Switch最新系统更新 修复数字商店bug
  20. 【又是一波重点】深度解析服务器科普知识 | CSDN博文精选

热门文章

  1. win10 请求操作需要提升解决方案
  2. word按backspace键不能删除问题
  3. 腾讯汤道生:产业互联网时代,安全成为CEO的一把手工程
  4. Bitmap、BitSet、RoaringBitmap持久化存储
  5. cs系统如何上云服务器,cs架构程序怎么连接云服务器
  6. NYOJ - [第十一届河南省程序设计大赛]治安管理(区间判断)
  7. c语言里strcpy作用是什么,c语言中的strcpy是什么意思?
  8. 打工能实现财富自由吗?--互联网老辛的思考
  9. 在启动时在Raspberry Pi上运行程序的五种方法
  10. python第六周拼图_python – 解决n-queen拼图