寒假学的两个算法,普里姆,克鲁斯卡尔最终弄明确了。能够发总结了

先说说普里姆,它的本质就是贪心。先从随意一个点開始,找到最短边,然后不断更新更新len数组,然后再选取最短边并标记经过的点,直到全部的点被标记。或者说已经选好了n-1条边。

拿SDUTOJ2144为例。代码例如以下,可做模板

#include <stdio.h>
#include <string.h>
#define INF 1000000 //最小生成树
//普里姆 int G[200][200];
int len[200];
bool vis[200]; int prm (int n)
{
int i,k,ans = 0;
memset (vis,0,sizeof(vis)); for (i = 2;i <= n;i++)//初始化
len[i] = G[1][i];
vis[1] = 1;
for (i = 1;i < n;i++) //循环n - 1次
{ //由于n个顶点的MST一定是n-1条边
int imin = INF,xb;
for (k = 1;k <= n;k++)
if (!vis[k] && imin > len[k])
{
imin = len[k];
xb = k;
} if (imin == INF) //没有找到最小值,说明图不连通
return -1; vis[xb] = 1;
ans += imin; for (k = 1;k <= n;k++)
if (!vis[k] && len[k] > G[xb][k])
len[k] = G[xb][k];
} return ans;
} int main()
{
int n,m; while (~scanf ("%d%d",&n,&m))
{
int i,k; for (i = 1;i <= n;i++)
for (k = 1;k <= n;k++)
if (i != k)
G[i][k] = INF;
else
G[i][k] = 0; for (i = 0;i < m;i++)
{
int a,b,c;
scanf ("%d%d%d",&a,&b,&c);
if (G[a][b] > c) //假设有边多次录入。选权最小的那个
G[a][b] = G[b][a] = c;
} int ans = prm(n); printf ("%d\n",ans);
}
return 0;
}

克鲁斯卡尔,一个排序一个并查集仅仅是表面。实质还是贪心,仅仅只是普里斯是任选一个点选最短路,而克鲁斯卡尔是看全局,全体边排序,当然,由于排序,导致时间复杂度不easy降下来。

相同的题,代码例如以下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INF 1000000 //最小生成树
//克鲁斯卡尔 int vis[200];
struct eg
{
int v,u,w;
}e[100000]; int cmp (const void *a,const void *b)
{
struct eg *ta = (struct eg *)a;
struct eg *tb = (struct eg *)b; return ta->w - tb->w;
} int fin (int a)
{
int r = a; while (vis[r] != r)
r = vis[r];
int k;
while (vis[a] != a)
{
k = vis[a];
vis[a] = r;
a = vis[k];
}
return r;
} int add (int a,int b)
{
vis[fin(a)] = fin (b);
return 0;
} int kls(int n,int m)
{
int i;
int ans = 0; for (i = 0;i <=n;i++)
vis[i] = i; for (i = 0;i < m;i++)
{
if (fin(e[i].u) != fin(e[i].v))
{
add (e[i].u,e[i].v);
ans += e[i].w;
}
} return ans;
} int main()
{
int n,m; while (~scanf ("%d%d",&n,&m))
{
int i,k;
for (i = 0;i < m;i++)
{
int a,b,c;
scanf ("%d%d%d",&a,&b,&c); e[i].u = a;
e[i].v = b;
e[i].w = c;
}
qsort(e,m,sizeof(e[0]),cmp);
int ans = kls(n,m); printf ("%d\n",ans);
}
return 0;
}

月球美容计划之最小生成树(MST)的更多相关文章

  1. 最小生成树MST算法(Prim、Kruskal)

    最小生成树MST(Minimum Spanning Tree) (1)概念 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边,所谓一个 ...

  2. POJ 1679 The Unique 次最小生成树 MST

    http://poj.org/problem?id=1679 题目大意: 给你一些点,判断MST(最小生成树)是否唯一. 思路: 以前做过这题,不过写的是O(n^3)的,今天学了一招O(n^2)的,哈 ...

  3. 最小生成树(MST)[简述][模板]

    Prim(添点法) 1. 任选一点(一般选1), 作为切入点,设其与最小生成树的距离为0(实际上就是选一个点,将此树实体化),. 2. 在所有未选择的点中选出与最小生成树距离最短的, 累计其距离, 并 ...

  4. 最小生成树MST

    定义 在一给定的无向联通带权图\(G = (V, E, W)\)中,\((u, v)\) 代表连接顶点 \(u\) 与顶点 \(v\) 的边,而 \(w(u, v)\) 代表此边的权重,若存在 \(T ...

  5. 【算法与数据结构】图的最小生成树 MST - Prim 算法

    Prim 算法属于贪心算法. #include <stdio.h> #define VERTEXNUM 7 #define INF 10000 typedef struct Graph { ...

  6. MST最小生成树及克鲁斯卡尔(Kruskal)算法

    最小生成树MST,英文名如何拼写已忘,应该是min spaning tree吧.假设一个无向连通图有n个节点,那么它的生成树就是包括这n个节点的无环连通图,无环即形成树.最小生成树是对边上权重的考虑, ...

  7. 【转载】最小生成树之Kruskal算法

    给定一个无向图,如果它任意两个顶点都联通并且是一棵树,那么我们就称之为生成树(Spanning Tree).如果是带权值的无向图,那么权值之和最小的生成树,我们就称之为最小生成树(MST, Minim ...

  8. Hdu 4081 最小生成树

    Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/3 ...

  9. 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind

    最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...

随机推荐

  1. Java设计模式学习记录-外观模式

    前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...

  2. 序列化(pickle,shelve,json,configparser)

    一,序列化 在我们存储数据或者网络传输数据的时候,需要对我们的对象进行处理,把对象处理成方便存储和传输的数据结构,这个过程叫序列化,不同的序列化,结果也不同,但是目的是一样的,都是为了存储和传输. 在 ...

  3. es6中的部分新特性

    1.es6中变量声明可以使用let声明变量,用const声明常量.例: test:function(){ { var num=10; let num1=11; const num2=12; } con ...

  4. 【原】PHP从入门到精通2小时【图文并茂】

    原创内容,转载请注明. 主要内容: 搭建PHP开发环境 第一个helloworld程序 变量 全局变量 循环结构 函数 数组 面向对象编程 继承 接口 多态 日志 文件的读写 时间格式和时区 创建图形 ...

  5. 【Mybatis】1、Mybatis拦截器学习资料汇总

    MyBatis拦截器原理探究 http://www.cnblogs.com/fangjian0423/p/mybatis-interceptor.html [myBatis]Mybatis中的拦截器 ...

  6. matlab中常数下的点是什么意思

    加上点"."后表示两个矩阵或向量对应位置进行运算, 这时候要求进行操作的两个变量必须维数相同(与矩阵乘法对矩阵维数要求不同)

  7. JavaSE 集合概述

    1.对象的存储: 数组(基本数据类型 & 引用数据类型) 集合(引用数据类型) 2.集合框架 Collection 接口: 方法: iterator().toArray();  迭代器遍历集合 ...

  8. vue和webpack打包 项目相对路径修改

    一般vue使用webpack打包是整个工程的根目录,但是很多情况下都是把vue打包后的文件在某子目录下. 修改: 1,打开index.js assetsPublicPath:'/' 改为: asset ...

  9. Java数据解析---JSON

    一.Java数据解析分为:XML解析和JSON解析 XML解析即是对XML文件中的数据解析,而JSON解析即对规定形式的数据解析,比XML解析更加方便 JSON解析基于两种结构: 1.键值对类型 { ...

  10. C#基础(数据类型运算符)

    ---恢复内容开始--- 1.类 修饰符 class 类名 基类或接口 { } 2.命名规范 成员变量前加_ 首字符小写,后面单词首字母大写(Camel规则) 接口首字母为I 方法的命名使用动词 所有 ...