hdu1233 最小生成树Prim算法和Kruskal算法
Prim算法
时间复杂度:O(\(N^2\),N为结点数)
说明:先任意找一个点标记,然后每次找一条最短的两端分别为标记和未标记的边加进来,再把未标记的点标记上。即每次加入一条合法的最短的边,每次扩展一个点由未标记为已标记,直至扩展为N个点。
#include<stdio.h>
#include<string.h>
#define MAX 100000000
int map[101][101],visit[101]; /*map[x][y]记录x点到y点的距离,visit[],记录点是否标记。*/
long long prim(int n);
int main()
{
int n;
while(scanf("%d",&n)&&n)
{
int m = n*(n-1)/2;
int i,j,a,b,c;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j) map[i][j] = 0;
else map[i][j]=map[j][i]=MAX;
}
}
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
map[a][b]=map[b][a]=c; /*初始完map[][]*/
}
long long ans = prim(n);
printf("%lld\n",ans);
}
return 0;
}
long long prim(int n)
{
long long ans = 0;
int minimal[510],i,j,min,k;
memset(minimal,0,sizeof(minimal));
memset(visit,0,sizeof(visit));
visit[1] = 1; /*从1开始,标记1*/
for(i=1;i<=n;i++) minimal[i] = map[1][i]; /*得到从开始点到其它个点的距离。*/
for(i=1;i<n;i++)
{
min = MAX;
for(j=1;j<=n;j++)
{
if(minimal[j]<min&&visit[j]==0)
{
min = minimal[j]; /*得到其它未标记点到标记点的最短距离。*/
k = j; /*得到最短距离的未标记点*/
}
}
ans += min;
visit[k] = 1; /*把未标记点标记*/
for(j=1;j<=n;j++)
{
if(minimal[j]>map[k][j]&&visit[j]==0&&k!=j)
{
minimal[j] = map[k][j]; /*重新初始其它未标记点到标记点的距离,若其它未标记点到新标记点k的距离更短则替换。*/
}
}
}
return ans;
}
Kruskal算法
时间复杂度:O(\(M\log_2{M}\),M为边数)
说明:Kruskal是通过一个贪心的想法,每次取剩下的边权最小的边,如果加上这条边以后图中出现一个环,则破坏了生成树的性质,就不选这条边。依次进行直到整张图出现一颗生成树为止。
hdu的oj里的G++好像不支持二维数组排序,这个代码不能过
#include<stdio.h>
#define N 105
int set[N];
int comp(const void *a,const void *b);
long long as(int sz[][3],int n,int a);
int fine(int a);
int main()
{
int n;
while(scanf("%d",&n)&&n)
{
int m = n*(n-1)/2;
int sz[m][3],i;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&sz[i][0],&sz[i][1],&sz[i][2]);
}
for(i=0;i<N;i++) set[i] = i;
qsort(sz,m,sizeof(int)*3,comp);
long long ans = as(sz,m,n);
printf("%lld\n",ans);
}
return 0;
}
int comp(const void *a,const void *b)
{
return ((int *)a)[2]-((int *)b)[2];
}
int fine(int a)
{
return a==set[a] ? a : (set[a]=fine(set[a]));
}
long long as(int sz[][3],int n,int a)
{
long long ans = 0;
int i;
for(i=0;i<n;i++)
{
if(fine(sz[i][0])!=fine(sz[i][1]))
{
set[fine(sz[i][1])] = fine(sz[i][0]);
ans += sz[i][2];
a--;
if(a==1) break;
}
else continue;
}
return ans;
}
重新把二维数组排序写成函数后就可以过了。
#include<stdio.h>
#define N 105
int set[N];
void qsort(int sz[][3],int a); /*二维数组排序的函数*/
long long as(int sz[][3],int n,int a);
int fine(int a);
int main()
{
int n;
while(scanf("%d",&n)&&n)
{
int m = n*(n-1)/2;
int sz[m][3],i;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&sz[i][0],&sz[i][1],&sz[i][2]);
}
for(i=0;i<N;i++) set[i] = i;
qsort(sz,m); /*按边排序*/
long long ans = as(sz,m,n);
printf("%lld\n",ans);
}
return 0;
}
void qsort(int sz[][3],int a)
{
int i,j,x,exchange;
for(i=0;i<a-1;i++)
{
for(j=i+1;j<a;j++)
{
if(sz[i][2]>sz[j][2])
{
for(x=0;x<3;x++)
{
exchange = sz[i][x];
sz[i][x] = sz[j][x];
sz[j][x] = exchange;
}
}
}
}
}
int fine(int a)
{
return a==set[a] ? a : (set[a]=fine(set[a]));
}
long long as(int sz[][3],int n,int a)
{
long long ans = 0;
int i,j;
for(i=0;i<n;i++)
{
if(fine(sz[i][0])!=fine(sz[i][1])) /*连接该边不构成环*/
{
set[fine(sz[i][1])] = fine(sz[i][0]);
ans += sz[i][2];
j++;
if(j==a-1) break; /*边数==点数-1即生成树完成。*/
}
}
return ans;
}
hdu1233 最小生成树Prim算法和Kruskal算法的更多相关文章
- 转载:最小生成树-Prim算法和Kruskal算法
本文摘自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html 最小生成树-Prim算法和Kruskal算法 Prim算 ...
- 最小生成树Prim算法和Kruskal算法
Prim算法(使用visited数组实现) Prim算法求最小生成树的时候和边数无关,和顶点树有关,所以适合求解稠密网的最小生成树. Prim算法的步骤包括: 1. 将一个图分为两部分,一部分归为点集 ...
- 最小生成树——Prim算法和Kruskal算法
洛谷P3366 最小生成树板子题 这篇博客介绍两个算法:Prim算法和Kruskal算法,两个算法各有优劣 一般来说当图比较稀疏的时候,Kruskal算法比较快 而当图很密集,Prim算法就大显身手了 ...
- 最小生成树---Prim算法和Kruskal算法
Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...
- 最小生成树Prim算法和Kruskal算法(转)
(转自这位大佬的博客 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html ) Prim算法 1.概览 普里姆算法(Pr ...
- 最小生成树之Prim算法和Kruskal算法
最小生成树算法 一个连通图可能有多棵生成树,而最小生成树是一副连通加权无向图中一颗权值最小的生成树,它可以根据Prim算法和Kruskal算法得出,这两个算法分别从点和边的角度来解决. Prim算法 ...
- java实现最小生成树的prim算法和kruskal算法
在边赋权图中,权值总和最小的生成树称为最小生成树.构造最小生成树有两种算法,分别是prim算法和kruskal算法.在边赋权图中,如下图所示: 在上述赋权图中,可以看到图的顶点编号和顶点之间邻接边的权 ...
- 【数据结构】最小生成树之prim算法和kruskal算法
在日常生活中解决问题经常需要考虑最优的问题,而最小生成树就是其中的一种.看了很多博客,先总结如下,只需要您20分钟的时间,就能完全理解. 比如:有四个村庄要修四条路,让村子能两两联系起来,这时就有最优 ...
- Prim算法和Kruskal算法
Prim算法和Kruskal算法都能从连通图找出最小生成树.区别在于Prim算法是以某个顶点出发挨个找,而Kruskal是先排序边,每次选出最短距离的边再找. 一.Prim(普里姆算法)算法: ...
随机推荐
- ACM基础板子
新生赛以后就正式成为一名acmer啦 ~虽然没有打过比赛呜呜呜 要好好学算法,拿一个牌牌嘛~ 这里就记录算法学习情况,也怕自己偷懒,学一个就记录,看看长时间拖更就是在摸鱼,摸鱼和鸽子都是本质 ,加油! ...
- CRM系统全方位管理企业
您在选择一款CRM系统的时候,首先要考虑销售团队的感受和意见.让CRM系统在帮助销售团队优化工作流程的同时,更好地对销售团队进行管理.销售人员每卖出一件商品,要从寻找筛选商机开始,经过沟通客户需求.满 ...
- PostgreSQL条件表达式
条件表达式在日常工作中很多场景都会用到,比如某个字段为空,取另外一个字段:某个值大于多少,取什么字段,小于多少取什么字段等等.那么下面来简单的学习下PostgreSQL有那些条件表达式. 1.CA ...
- 【建议收藏】缺少 Vue3 和 Spring Boot 的实战项目经验?我这儿有啊!
缺少 Vue3 和 Spring Boot 的实战项目经验?缺少学习项目和练手项目?我这儿有啊! 从 2019 年到 2021 年,空闲时间里陆陆续续做了一些开源项目,推荐给大家啊!记得点赞和收藏噢! ...
- HTML的表格元素
一.HTML的表格元素 1.table元素 <table> 标签定义 HTML 表格.简单的 HTML 表格由 table 元素以及一个或多个 tr.th 或 td 元素组成.tr 元素定 ...
- 系统区域设置 本地语言的支持依赖于 /etc/locale.conf,/etc/locale.conf 包含不少于此相关的环境变量
https://linux.cn/lfs/LFS-BOOK-7.7-systemd/chapter07/locale.html 7.7. 系统区域设置 本地语言的支持依赖于 /etc/locale.c ...
- vi/vim输入中文乱码,无法输入中文解决方法
vi/vim输入中文乱码,无法输入中文解决方法 编辑/etc/vimrc或者/etc/virc,加入以下内容即可 set encoding=UTF-8 set langmenu=zh_CN.UTF-8 ...
- 像素 PIXEL 图片的基本单位 像素非常小 图片是成千上万的像素组成 显示/屏幕分辨率 (DPI 屏幕分辨率)
像素 PIXEL 图片的基本单位 像素非常小 图片是成千上万的像素组成 显示/屏幕分辨率 (DPI 屏幕分辨率) 图像分辨率 (PPI) 1920*1080是像素点长度1920个像素点 X1080个像 ...
- ELK学习实验020:ELK使用kafka缓存
首先安装一个kafka集群,但是zookeeper使用单节点,可以让kafka快速跑起来,后续再研究kafka和zokkeeper的集群 1 安装Kafka集群 下面是三个节点都要做 [root@no ...
- Lua _G
1.全局变量的原形 在Lua中,要声明全局变量很简单,那就是定义变量的时候,前面不要加上local. 这个神秘的全局变量,其实本质上也是一个table,它把我们创建的全局变量都保存到一个table里了 ...