最小生成树模板总结--PrimKruskal
一.最小生成树:连通N个点的边权值总和最小的树。
二.时间复杂度
Prim算法:时间复杂度O(|V|2+|E|),O(|E|log|V|)
Kruskal算法:时间复杂度O(|E|log|E|)
算法的选择: 从图的稀疏程度考虑(稠密图Prim,稀疏图Kruskal或Prim + Heap)
三.具体算法
1.Prim算法:(1) 任意选定一点s,设集合S={s}
(2) 从不在集合S的点中选出一个点j使得其与S内的某点i的距离最短,则(i,j)就是生成树上的一条边,同时将j点加入S
(3) 转到(2)继续进行,直至所有点都己加入S集合
Prim模板:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #include <vector> #define Twhile() int T;scanf("%d",&T);while(T--) #define ArrInit(a,b,n) for(int i=0;i<=n;i++)a[i]=b #define ArrInit2(a,b,n,m) for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)a[i][j]=b #define fora(i,a,b) for(int i=a;i<b;i++) #define fors(i,a,b) for(int i=a;i>b;i--) #define fora2(i,a,b) for(int i=a;i<=b;i++) #define fors2(i,a,b) for(int i=a;i>=b;i--) #define PI acos(-1.0) #define eps 1e-6 #define INF 0x3f3f3f3ftypedef long long LL; typedef long long LD; using namespace std; const int maxn=2000+11; int ma[maxn][maxn]; int N,M;//点数,边数 int ans;//最小生成树的权值之和 //stack<int>S; //最小生成树加入的点的顺序 //int lowerPoint[maxn]; // i离S中的lowerPoint[i]最近 int lowerCost[maxn],use[maxn];//lowerCost离S的最小距离,use是否被加入S void init() {ans=0;ArrInit2(ma,INF,N,N);ArrInit(use,0,N); } void primInit() { // S.push(1);use[1]=1;lowerCost[1]=0; // lowerPoint[1]=1;fora2(i,2,N){ // lowerPoint[i]=1;lowerCost[i]=ma[1][i];} } void prim() {primInit();int n=N-1;while(n--){int k=-1,tem=INF;fora2(i,2,N)//找到距离S集合最小的点 {if(use[i])continue;if(lowerCost[i]<tem){tem=lowerCost[i];k=i;}}use[k]=1;ans+=tem;/*lowerCost[k]=0;lowerPoint[i]=i; //不更新的话,当要求输出最小生成树的边可以直接输出S.push(k);*/fora2(i,1,N){if(use[i])continue;int t=ma[i][k];if(t<lowerCost[i]){lowerCost[i]=t;//lowerPoint[i]=k; }}if(tem==INF)return;//图不连通 } }int main() {while(~scanf("%d",&N)&&N){scanf("%d",&M);init();while(M--){int x,y,z;scanf("%d%d%d",&x,&y,&z);ma[x][y]=min(ma[x][y],z);ma[y][x]=min(ma[y][x],z);}if(N==1){printf("0\n");continue;}prim();printf("%d\n",ans);}return 0; }
View Code
例子:UVALive - 2515 Networking
UVA - 10369
2.Kruskal算法:(1) 将边按权值从小到大排序后逐个判断,如果当前的边加入以后不会产生环,那么就把当前边作为生成树的一条边
(2) 最终得到的结果就是最小生成树
Kruskal模板:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #include <vector> #define Twhile() int T;scanf("%d",&T);while(T--) #define ArrInit(a,b,n) for(int i=0;i<=n;i++)a[i]=b #define ArrInit2(a,b,n,m) for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)a[i][j]=b #define fora(i,a,b) for(int i=a;i<b;i++) #define fors(i,a,b) for(int i=a;i>b;i--) #define fora2(i,a,b) for(int i=a;i<=b;i++) #define fors2(i,a,b) for(int i=a;i>=b;i--) #define PI acos(-1.0) #define eps 1e-6 #define INF 0x3f3f3f3ftypedef long long LL; typedef long long LD; using namespace std; const int maxn=5000+11; int N,M,ans;//点,边,最小生成树 struct edge {int u,v;//点u到vint var;//权值 }ma[maxn]; bool cmp(edge a,edge b) {return a.var<b.var; } int fa[maxn]; void initKruskal() {ans=0;fora2(i,1,N){fa[i]=i;}sort(ma+1,ma+M+1,cmp);} /* Kruskal算法 (1) 将边按权值从小到大排序后逐个判断,如果当前的边加入以后不会产生环,那么就把当前边作为生成树的一条边 (2) 最终得到的结果就是最小生成树 并查集 */ int findx(int x) {if(x==fa[x])return x;return fa[x]=findx(fa[x]); } bool unio(int x,int y) {int fx=findx(x),fy=findx(y);if(fx==fy)return false;fa[fy]=fx;return true; } void kruskal() {initKruskal();int m=0;fora2(i,1,M){if(unio(ma[i].u,ma[i].v)){m++;ans+=ma[i].var;//printf("%d %d %d\n",ma[i].u,ma[i].v,m); }if(m==N-1)return;} }
View Code
例子:UVALive - 2515 Networking
转载于:https://www.cnblogs.com/107acm/p/9437527.html
最小生成树模板总结--PrimKruskal相关推荐
- 图论--最小生成树总结(PrimKruskal)
今天才写了prim的堆优化,发现kruskal居然比prim跑得快... 回归正题: 以下是我个人对最小生成树各种算法的理解,以及我的代码. 以下我将点数称为n,边数称为m: Prim 算法过程(来自 ...
- 最小生成树模板 POJ——1258
最小生成树是一个比较简单数据结构,形成最小生成树的方式有两种. 最小生成树是有图生成树,保证树的每条边的权值之和最小的生成树就叫做最小生成树,这一类的题目起初比较基础,主要是熟悉模板,POJ 1258 ...
- 最小生成树(模板题:最优布线问题,繁忙的都市,联络员)(C++)
文章目录 序言 正文 First Promble 最优布线问题 时间限制: 1000 m s 1000 ms 1000ms 空间限制: 262144 K B 262144 KB 262144KB 题目 ...
- 畅通工程(最小生成树模板)
题目描述 给出无向图中M个节点间N条边的权值. 求一个使得所有点连通的子图,要求图内的边权和最小 Input 测试输入包含若干测试用例 每个测试用例的第1行包含N.M ( <100 ) 随后的 ...
- 天空之城(最小生成树模板题)
题目描述 **链接:https://ac.nowcoder.com/acm/contest/9986/J 来源:牛客网 天空之城有5个小镇,名字分别为Ada, Aed, Akk, Orz, Apq,他 ...
- 最小生成树模板题 P1692
Description 给出N个顶点.E条边的连通无向简单图,请你完成下列任务: 任务1.求边权和最小的生成树(最小生成树) 任务2.求边权和最大的生成树(最大生成树) 任务3.求最大边最小的生成树( ...
- POJ3164 最小树形图 有向图的最小生成树 模板题 朱刘算法 朱永津-刘振宏算法
Command Network Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 12833 Accepted: 3717 ...
- 【kuangbin带你飞】专题六 最小生成树
[kuangbin带你飞]专题六 最小生成树 A.POJ - 1251 Jungle Roads (最小生成树模板) The Head Elder of the tropical island of ...
- CSP认证201412-4 最优灌溉[C++题解]:最小生成树裸题、Kruskal算法求最小生成树
题目分析 来源:acwing 分析:这是一道最小生成树的裸题. 这里默写Kruskal求最小生成树的最小费用的模板. 最小生成树模板请参考笔者的另一篇博文: 最小生成树板子-AcWing 859. K ...
最新文章
- 卧槽!华为大佬整理的Linux学习笔记和资料不小心流落到了外网.……
- 通过反射实现IOC功能
- 实现Windows non-Unicode设置批量修改
- 大数据读书笔记(1)
- day011_步入百万年薪的第十一天
- java instanceof 继承_继承_instanceOf的使用
- 网络流专题(最大流与费用流)(一)
- 伪原创工具安全第一嘛~~
- 嵌入式Linux入门3:Linux服务器搭建
- 【转】Tcl/Tk 漫谈
- ORACLE 随机数 dbms_random
- nginx 之 proxy_pass详解
- wordpress搭建 ubuntu16.04 apache2 + php7.0 + mysql
- 计算时间间隔 日历牌上的 周数
- 2019年安徽省学业水平考试计算机,2019年安徽省初中学业水平考试
- DSP DTK6437、seed6437 通过指定的定标数据生成梯形波(带串口通信)
- windows 编译n2n
- POI Word单元格合并
- 万能密码为什么能成功
- userdel删除用户时候提示:userdel: user xx is currently logged in
热门文章
- 全球富豪大洗牌!马斯克登顶世界首富,黄铮国内第三超马云
- GitHub 标星 2.5K+,U^2-Net 跨界肖像画,完美复刻人物细节!
- 程序员看过来!JS、Java、C 依然强势,Go、Kotlin、Python 潜力股,2020 开发者生态系统报告
- MOSS2007最终用户培训资料
- spring mvc-REST
- 在 iOS 11 中使用 Core Bluetooth
- Xtrabackup备份、还原、恢复Mysql操作大全
- bzoj 2160: 拉拉队排练
- MySQL DATE_FORMATE函数内置字符集的坑
- 简单例子解释invalidate(), requestLayout() (常用还是需要知道的)