一.最小生成树:连通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相关推荐

  1. 图论--最小生成树总结(PrimKruskal)

    今天才写了prim的堆优化,发现kruskal居然比prim跑得快... 回归正题: 以下是我个人对最小生成树各种算法的理解,以及我的代码. 以下我将点数称为n,边数称为m: Prim 算法过程(来自 ...

  2. 最小生成树模板 POJ——1258

    最小生成树是一个比较简单数据结构,形成最小生成树的方式有两种. 最小生成树是有图生成树,保证树的每条边的权值之和最小的生成树就叫做最小生成树,这一类的题目起初比较基础,主要是熟悉模板,POJ 1258 ...

  3. 最小生成树(模板题:最优布线问题,繁忙的都市,联络员)(C++)

    文章目录 序言 正文 First Promble 最优布线问题 时间限制: 1000 m s 1000 ms 1000ms 空间限制: 262144 K B 262144 KB 262144KB 题目 ...

  4. 畅通工程(最小生成树模板)

    题目描述 给出无向图中M个节点间N条边的权值. 求一个使得所有点连通的子图,要求图内的边权和最小 Input 测试输入包含若干测试用例 每个测试用例的第1行包含N.M ( <100 ) 随后的 ...

  5. 天空之城(最小生成树模板题)

    题目描述 **链接:https://ac.nowcoder.com/acm/contest/9986/J 来源:牛客网 天空之城有5个小镇,名字分别为Ada, Aed, Akk, Orz, Apq,他 ...

  6. 最小生成树模板题 P1692

    Description 给出N个顶点.E条边的连通无向简单图,请你完成下列任务: 任务1.求边权和最小的生成树(最小生成树) 任务2.求边权和最大的生成树(最大生成树) 任务3.求最大边最小的生成树( ...

  7. POJ3164 最小树形图 有向图的最小生成树 模板题 朱刘算法 朱永津-刘振宏算法

    Command Network Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 12833   Accepted: 3717 ...

  8. 【kuangbin带你飞】专题六 最小生成树

    [kuangbin带你飞]专题六 最小生成树 A.POJ - 1251 Jungle Roads (最小生成树模板) The Head Elder of the tropical island of ...

  9. CSP认证201412-4 最优灌溉[C++题解]:最小生成树裸题、Kruskal算法求最小生成树

    题目分析 来源:acwing 分析:这是一道最小生成树的裸题. 这里默写Kruskal求最小生成树的最小费用的模板. 最小生成树模板请参考笔者的另一篇博文: 最小生成树板子-AcWing 859. K ...

最新文章

  1. 卧槽!华为大佬整理的Linux学习笔记和资料不小心流落到了外网.……
  2. 通过反射实现IOC功能
  3. 实现Windows non-Unicode设置批量修改
  4. 大数据读书笔记(1)
  5. day011_步入百万年薪的第十一天
  6. java instanceof 继承_继承_instanceOf的使用
  7. 网络流专题(最大流与费用流)(一)
  8. 伪原创工具安全第一嘛~~
  9. 嵌入式Linux入门3:Linux服务器搭建
  10. 【转】Tcl/Tk 漫谈
  11. ORACLE 随机数 dbms_random
  12. nginx 之 proxy_pass详解
  13. wordpress搭建 ubuntu16.04 apache2 + php7.0 + mysql
  14. 计算时间间隔 日历牌上的 周数
  15. 2019年安徽省学业水平考试计算机,2019年安徽省初中学业水平考试
  16. DSP DTK6437、seed6437 通过指定的定标数据生成梯形波(带串口通信)
  17. windows 编译n2n
  18. POI Word单元格合并
  19. 万能密码为什么能成功
  20. userdel删除用户时候提示:userdel: user xx is currently logged in

热门文章

  1. 全球富豪大洗牌!马斯克登顶世界首富,黄铮国内第三超马云
  2. GitHub 标星 2.5K+,U^2-Net 跨界肖像画,完美复刻人物细节!
  3. 程序员看过来!JS、Java、C 依然强势,Go、Kotlin、Python 潜力股,2020 开发者生态系统报告
  4. MOSS2007最终用户培训资料
  5. spring mvc-REST
  6. 在 iOS 11 中使用 Core Bluetooth
  7. Xtrabackup备份、还原、恢复Mysql操作大全
  8. bzoj 2160: 拉拉队排练
  9. MySQL DATE_FORMATE函数内置字符集的坑
  10. 简单例子解释invalidate(), requestLayout() (常用还是需要知道的)