POJ-图论-最小生成树模板

Kruskal算法

1.初始时所有结点属于孤立的集合。

2.按照边权递增顺序遍历所有的边,若遍历到的边两个顶点仍分属不同的集合(该边即为连通这两个集合的边中权值最小的那条)则确定该边为最小生成树上的一条边,并将这两个顶点分属的集合合并。

3.遍历完所有边后,原图上所有结点属于同一个集合则被选取的边和原图中所有结点构成最小生成树;否则原图不连通,最小生成树不存在。

数据结构:引入边结构,并重载小于号运算符

struct Edge
{
int a, b;//边的两端结点编号
int cost;//边的权值
bool operator <(const Edge &A)const
{
return cost < A.cost;//边权从小到大排列
}
}edge[];

用并查集来实现集合操作

void init()
{
for (int i = ; i <= n; i++)p[i] = i;
ans = ;
} int find(int x)
{
return (x == p[x]) ? x : p[x] = find(p[x]);
} void Union(int i)//以边为单位合并
{
int a = find(edge[i].a);
int b = find(edge[i].b);//查找边的两个顶点所在集合的信息
if (a != b) //若他们属于不同集合,则选用该边
{
p[b] = a;//合并集合
ans += edge[i].cost;//累加权值
}
}

例 5.3 还是畅通工程

#include<cstdio>
#include<algorithm>
using namespace std;
const int N = ; int p[N];//父结点数组
int n;//结点数量
int ans;//最小权值和 struct Edge
{
int a, b;//边的两端结点编号
int cost;//边的权值
}edge[]; bool cmp(Edge a, Edge b)
{
return a.cost<b.cost;
} void init()
{
for (int i = ; i <= n; i++)p[i] = i;
ans = ;
} int find(int x)
{
return (x == p[x]) ? x : p[x] = find(p[x]);
} void Union(int i)//以边为单位合并
{
int a = find(edge[i].a);
int b = find(edge[i].b);//查找边的两个顶点所在集合的信息
if (a != b) //若他们属于不同集合,则选用该边
{
p[b] = a;//合并集合
ans += edge[i].cost;//累加权值
}
} int main()
{
while (scanf("%d", &n) != EOF && n != )
{
for (int i = ; i <= n * (n - ) / ; i++) scanf("%d%d%d", &edge[i].a, &edge[i].b, &edge[i].cost);
sort(edge + , edge + + n * (n - ) / , cmp);//起始元素为edge[1],一共n * (n - 1) / 2个待排序元素
init();
for (int i = ; i <= n * (n - ) / ; i++) Union(i);
printf("%d\n", ans);
}
return ;
}
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = ; int p[N];//父结点数组
int n;//结点数量
int ans;//最小权值和 struct Edge
{
int a, b;//边的两端结点编号
int cost;//边的权值
bool operator <(const Edge &A)const
{
return cost < A.cost;//边权从小到大排列
}
}edge[]; void init()
{
for (int i = ; i <= n; i++)p[i] = i;
ans = ;
} int find(int x)
{
return (x == p[x]) ? x : p[x] = find(p[x]);
} void Union(int i)//以边为单位合并
{
int a = find(edge[i].a);
int b = find(edge[i].b);//查找边的两个顶点所在集合的信息
if (a != b) //若他们属于不同集合,则选用该边
{
p[b] = a;//合并集合
ans += edge[i].cost;//累加权值
}
} int main()
{
while (scanf("%d", &n) != EOF && n != )
{
for (int i = ; i <= n * (n - ) / ; i++) scanf("%d%d%d", &edge[i].a, &edge[i].b, &edge[i].cost);
sort(edge + , edge + + n * (n - ) / );//起始元素为edge[1],一共n * (n - 1) / 2个待排序元素
init();
for (int i = ; i <= n * (n - ) / ; i++) Union(i);
printf("%d\n", ans);
}
return ;
}

重载Edge小于号

POJ-图论-最小生成树模板的更多相关文章

  1. poj 1258 最小生成树 模板

    POJ 最小生成树模板 Kruskal算法 #include<iostream> #include<algorithm> #include<stdio.h> #in ...

  2. Poj 2187 凸包模板求解

    Poj 2187 凸包模板求解 传送门 由于整个点数是50000,而求凸包后的点也不会很多,因此直接套凸包之后两重循环即可求解 #include <queue> #include < ...

  3. 图论-最小生成树<Kruskal>

    昨天: 图论-最小生成树<Dijkstra,Floyd> 以上是昨天的Blog,有需要者请先阅读完以上再阅读今天的Blog. 可能今天的有点乱,好好理理,认真看完相信你会懂得 然而,文中提 ...

  4. POJ 2031 Building a Space Station 最小生成树模板

    题目大意:在三维坐标中给出n个细胞的x,y,z坐标和半径r.如果两个点相交或相切则不用修路,否则修一条路连接两个细胞的表面,求最小生成树. 题目思路:最小生成树树模板过了,没啥说的 #include& ...

  5. 最小生成树模板题POJ - 1287-prim+kruskal

    POJ - 1287超级模板题 大概意思就是点的编号从1到N,会给你m条边,可能两个点之间有多条边这种情况,求最小生成树总长度? 这题就不解释了,总结就算,prim是类似dijkstra,从第一个点出 ...

  6. poj 1251 poj 1258 hdu 1863 poj 1287 poj 2421 hdu 1233 最小生成树模板题

    poj 1251  && hdu 1301 Sample Input 9 //n 结点数A 2 B 12 I 25B 3 C 10 H 40 I 8C 2 D 18 G 55D 1 E ...

  7. POJ 1789 Truck History (Kruskal最小生成树) 模板题

    Description Advanced Cargo Movement, Ltd. uses trucks of different types. Some trucks are used for v ...

  8. POJ 1258:Agri-Net Prim最小生成树模板题

    Agri-Net Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 45050   Accepted: 18479 Descri ...

  9. POJ 1287 Networking (最小生成树模板题)

    Description You are assigned to design network connections between certain points in a wide area. Yo ...

随机推荐

  1. winfrom数据导出

    /// <summary> /// 数据导出 /// </summary> /// <param name="dataGridView">< ...

  2. 我是如何一步步编码完成万仓网ERP系统的(四)登录的具体实现

    https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...

  3. 在微博微信场景下学习Redis数据结构

    Redis安装 下载地址:http://redis.io/download 安装步骤: 1.yum install gcc 2.wget http://download.redis.io/releas ...

  4. Flask路由系统

    Flask路由系统 我们之前了解了路由系统是由带参数的装饰器完成的. 路由本质:装饰器和闭包实现的. 设置路由的两种方式 第一种: @app.route('/index') def index(): ...

  5. kingbase常用语句

    1. 查询数据库名 # select * from SYS_DATABASE; 2. 查询模式名 # select * from SYS_NAMESPACE; 3. 查询表空间 # select * ...

  6. H5离线缓存(基础)学习指南

    离线缓存 application cache 1. 什么是离线缓存: 离线缓存可以将站点的一些文件缓存到本地,它是浏览器自己的一种机制,将需要的文件缓存下来,以便后期即使没有连接网络,被缓存的页面也可 ...

  7. Mysql-修改用户连接数据库IP地址和用户名

    将用户连接数据库(5.7.14-7)的IP地址从 10.10.5.16   修改为 10.11.4.197 Mysql> rename user 'username'@'10.10.5.16' ...

  8. cookie跨域解决方案

    cookie的名/值对中的值不允许出现分号.逗号和空白符,因此在设置cookie前要用encodeURIComponent()编码,读取时再用decodeURIComponent()解码. cooki ...

  9. 使用Git Flow规范!

    Git Flow常用的分支 Production 分支 也就是我们经常使用的Master分支,这个分支最近发布到生产环境的代码,最近发布的Release, 这个分支只能从其他分支合并,不能在这个分支直 ...

  10. 【MySQL】自增步长调整

    mysql> show variables like '%increment%'; +-----------------------------+-------+ | Variable_name ...