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小于号

最新文章

  1. CSS制作三角形和按钮
  2. Android版本4.0~7.0
  3. NFS挂载Android文件系统
  4. Struts2中的namespace使用
  5. Varnish缓存服务器的搭建配置手册
  6. HDU - 5156 Harry and Christmas tree
  7. AIX-du
  8. sina微博上看到的关于android界面设计相关的规范
  9. Dynamics CRM 2013 Homepage Ribbon 按钮引用多个Javascript资源
  10. Java线程同步锁
  11. Core官方DI剖析(1)--ServiceProvider类和ServiceCollection类
  12. MySQL的SQL_Mode修改小计
  13. IntelliJ IDEA 的使用方法总结
  14. CDRAF之Service mesh
  15. 阻止 form 回车 自动提交
  16. Android Studio 修改包名最便捷做法
  17. centos7.3 64位 安装git
  18. SpringData中使用@Modifying注解实现修改操作
  19. DMS路由表
  20. alsa-lib、alsa-utils移植

热门文章

  1. springmvc之静态资源访问不到 -记一次惨痛的经历
  2. Object.freeze
  3. 隐马尔科夫模型(Hidden Markov Models) 系列之一
  4. 某安全设备未授权访问+任意文件下载0day
  5. APS系统帮助寻找企业最优库存
  6. Linux从入门到放弃、零基础入门Linux(第四篇):在虚拟机vmware中安装centos7.7
  7. MySQL基础SQL命令---增删改查
  8. postgresql设置max_connections太大无法启动 (转载)
  9. springboot集成spring data ElasticSearch
  10. 微软源码站点-C#编程指南