无向图最小生成树(prim算法)
普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克发现;并在1957年由美国计算机科学家罗伯特·普里姆独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法
算法过程图解:遍历点,用贪心法选择与集合内的点相连的点的最小值;
模板:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define zero_(x,y) memset(x , y , sizeof(x))
#define zero(x) memset(x , 0 , sizeof(x))
#define MAX(x) memset(x , 0x3f ,sizeof(x))
using namespace std;
#define N 1005
typedef long long LL ;
int G[N][N];
int minn[N];///寻找最小权;
bool point[N]; int main(){
//freopen("in.txt","r",stdin);
memset(point, , sizeof(point));
int n, m, x, y, ans=;
scanf("%d%d", &n, &m);
for(int i=;i<=n;i++){
for(int j = ; j <= n; j++){
G[i][j] = INF;
}
}
for(int i = ; i <= m; i++) {
scanf("%d%d", &x, &y);
scanf("%d", &G[x][y]);
G[y][x] = G[x][y];
}
point[] = true;
for(int i = ;i <= n; i++) minn[i] = G[][i];
for(int i = ; i <= n; i++){
int k = , mi = INF;
for(int j = ; j <= n; j++){
if(!point[j] && minn[j] < mi){
mi = minn[j];
k = j;
}
}
ans += minn[k];
point[k] = true;
for(int s = ;s <= n; s++){
if(!point[s] && G[k][s] < minn[s])///保存了之前没有加入集合的边的权;
minn[s] = G[k][s];
}
}
printf("%d\n", ans);
return ;
}
题意:点是7位小写字母,边是小写字母间的不同字母数量(1-7)。求最小生成树。
边权:the number of positions with different letters in truck type codes.
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set> #define c_false ios_base::sync_with_stdio(false); cin.tie(0)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define zero_(x,y) memset(x , y , sizeof(x))
#define zero(x) memset(x , 0 , sizeof(x))
#define MAX(x) memset(x , 0x3f ,sizeof(x))
#define swa(x,y) {LL s;s=x;x=y;y=s;}
using namespace std ;
#define N 2005 const double PI = acos(-1.0);
typedef long long LL ;
int n, dis[N][N], minn[N];
char x[];
string type[N];
bool point[N]; int Distance(int i, int j){
int len = , sum = ;
for(int k = ; k < len; k++)
if(type[i][k] != type[j][k])
sum++;
return sum;
}
int prim(){
point[] = true;
int ans = ;
for(int i = ; i <= n; i++) minn[i] = dis[][i];
for(int i = ; i <= n; i++){
int k = ; int mi =INF;
for(int j = ; j <= n; j++){
if(!point[j] && minn[j] <mi){
mi = minn[j];
k = j;
}
}
ans += minn[k];
point[k] = true;
for(int s = ; s <= n; s++){
if(!point[s] && dis[k][s] <minn[s])
minn[s] = dis[k][s];
}
}
return ans;
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//ios_base::sync_with_stdio(false); cin.tie(0);
while(~scanf("%d", &n) && n){
zero(dis);zero(point);MAX(dis);
for(int i = ; i <= n; i++){
scanf("%s", x);
type[i] = x;
}
for(int i = ; i<= n; i++){
for(int j = ; j < i; j++){
dis[i][j] = dis[j][i] = Distance(i, j);
}
}
printf("The highest possible quality is 1/%d.\n", prim());
}
return ;
}
题意:求最小生成树的最大边权;(英语实在太烂)
point:minimize the length of the longest highway
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set> #define c_false ios_base::sync_with_stdio(false); cin.tie(0)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define zero_(x,y) memset(x , y , sizeof(x))
#define zero(x) memset(x , 0 , sizeof(x))
#define MAX(x) memset(x , 0x3f ,sizeof(x))
#define swa(x,y) {LL s;s=x;x=y;y=s;}
using namespace std ;
#define N 505 const double PI = acos(-1.0);
typedef long long LL ;
int T, n, dis[N][N], minn[N];
bool point[N]; int prim(){
point[] = true;
int ans = ;
for(int i = ; i <= n; i++) minn[i] = dis[][i];
for(int i = ; i <= n; i++){
int k = ; int mi =INF;
for(int j = ; j <= n; j++){
if(!point[j] && minn[j] <mi){
mi = minn[j];
k = j;
}
}
if(ans < minn[k]) ans = minn[k];
point[k] = true;
for(int s = ; s <= n; s++){
if(!point[s] && dis[k][s] <minn[s])
minn[s] = dis[k][s];
}
}
return ans;
} int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//ios_base::sync_with_stdio(false); cin.tie(0);
scanf("%d", &T);
while(T--){
zero(point);zero(dis);zero(minn);
scanf("%d", &n);
for(int i = ; i <= n; i++){
for(int j = ; j <= n; j++){
scanf("%d", &dis[i][j]);
}
}
printf("%d\n", prim());
}
return ;
}
简单模板题,同上;
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set> #define c_false ios_base::sync_with_stdio(false); cin.tie(0)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define zero_(x,y) memset(x , y , sizeof(x))
#define zero(x) memset(x , 0 , sizeof(x))
#define MAX(x) memset(x , 0x3f ,sizeof(x))
#define swa(x,y) {LL s;s=x;x=y;y=s;}
using namespace std ;
#define N 505 const double PI = acos(-1.0);
typedef long long LL ;
int n, dis[N][N], minn[N];
bool point[N]; int prim(){
point[] = true;
int ans = ;
zero(minn);zero(point);
for(int i = ; i <= n; i++) minn[i] = dis[][i];
for(int i = ; i <= n; i++){
int k = ; int mi =INF;
for(int j = ; j <= n; j++){
if(!point[j] && minn[j] <mi){
mi = minn[j];
k = j;
}
}
ans += minn[k];
point[k] = true;
for(int s = ; s <= n; s++){
if(!point[s] && dis[k][s] <minn[s])
minn[s] = dis[k][s];
}
}
return ans;
} int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//ios_base::sync_with_stdio(false); cin.tie(0);
while(~scanf("%d", &n) && n){
zero(dis);
for(int i = ; i <= n; i++){
for(int j = ; j <= n; j++){
scanf("%d", &dis[i][j]);
}
}
printf("%d\n", prim());
}
return ;
}
题意:求最小生成树;
思路:prim + BFS
这题的难点在于寻找邻接矩阵;
用BFS 找到各点间的最小距离的点;
然后就是套模板;
无向图最小生成树(prim算法)的更多相关文章
- 加权无向图 最小生成树 Prim算法 延迟版和即时版 村里修路该先修哪
本次要解决的问题是:你们村里那些坑坑洼洼的路,到底哪些路才是主干道? 小明:肯定是哪里都能到得了,并且去哪里都相对比较近,并且被大家共用程度高的路是啊! 具体是哪几条路呢?今天就可以给出准确答案 最小 ...
- 最小生成树—prim算法
最小生成树prim算法实现 所谓生成树,就是n个点之间连成n-1条边的图形.而最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int map[ ...
- Highways POJ-1751 最小生成树 Prim算法
Highways POJ-1751 最小生成树 Prim算法 题意 有一个N个城市M条路的无向图,给你N个城市的坐标,然后现在该无向图已经有M条边了,问你还需要添加总长为多少的边能使得该无向图连通.输 ...
- 图论算法(五)最小生成树Prim算法
最小生成树\(Prim\)算法 我们通常求最小生成树有两种常见的算法--\(Prim\)和\(Kruskal\)算法,今天先总结最小生成树概念和比较简单的\(Prim\)算法 Part 1:最小生成树 ...
- 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。
//归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...
- 最小生成树Prim算法(邻接矩阵和邻接表)
最小生成树,普利姆算法. 简述算法: 先初始化一棵只有一个顶点的树,以这一顶点开始,找到它的最小权值,将这条边上的令一个顶点添加到树中 再从这棵树中的所有顶点中找到一个最小权值(而且权值的另一顶点不属 ...
- SWUST OJ 1075 求最小生成树(Prim算法)
求最小生成树(Prim算法) 我对提示代码做了简要分析,提示代码大致写了以下几个内容 给了几个基础的工具,邻接表记录图的一个的结构体,记录Prim算法中最近的边的结构体,记录目标边的结构体(始末点,值 ...
- 最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析
最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析 最小生成树,老生常谈了,生活中也总会有各种各样的问题,在这里,我来带你一起分析一下这个算法的思路与实现的方式吧~~ 在考研中呢 ...
- 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind
最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...
- 数据结构:最小生成树--Prim算法
最小生成树:Prim算法 最小生成树 给定一无向带权图.顶点数是n,要使图连通仅仅需n-1条边.若这n-1条边的权值和最小,则称有这n个顶点和n-1条边构成了图的最小生成树(minimum-cost ...
随机推荐
- MyEclipse转换Eclipse项目无法启动问题(转)
将myeclipse中开发的动态web项目直接引入到eclipse中继续开发,启动tomcat时会发出警告,更重的问题是你想启动的项目不知哪里去了,没有读取到配置文件: 警告: [SetP ...
- 分析Tornado的协程实现
转自:http://www.binss.me/blog/analyse-the-implement-of-coroutine-in-tornado/ 什么是协程 以下是Wiki的定义: Corouti ...
- CentOS6.4 安装 erlang
wget http://www.erlang.org/download/otp_src_17.0.tar.gz -P /usr/local/src/ wget http://www.erlang.or ...
- Thinkpad 笔记本VMware Workstation 安装虚拟机出现“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”解决方法
今天在使用VMware打算在机器中安装新的虚拟机时,出现"此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态"错误如下: 提示信息: 已将该虚拟机配 ...
- python发邮件
# -*- coding:utf- -*- import smtplib,os,sys,string import mimetypes from email import Encoders from ...
- ios异常(crash)输出
最近突然想起友盟的sdk附带的一个功能:将闪退异常情况上报服务器,(stackflow,github)找了一些资料,自己写了一个demo,想起来好久没有写过blog了,顺便分享. 其实不止是ios,a ...
- json格式的时间转换
//yyyy-MM-dd HH:mm:SS function JsonDateToDate(jsondate) { var date = new Date(parseInt(jsondate.repl ...
- HTML中常用meta整理
< meta > 元素 定义 meta标签提供关于HTML文档的元数据.元数据不会显示在页面上,但是对于机器是可读的.它可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其 ...
- Ninject的使用
摘要 DI容器的一个责任是管理他创建的对象的生命周期.他应该决定什么时候创建一个给定类型的对象,什么时候使用已经存在的对象.他还需要在对象不需要的时候处理对象.Ninject在不同的情况下管理对象的生 ...
- “VS2013无法连接远程数据库”解决方案
“VS2013无法连接远程数据库” 解决方案:以管理员身份登录CMD,输入netsh winsock reset并回车(注意,必须是已管理员身份运行,这个重置LSP连接) 或 netsh winsoc ...