畅通工程(最小生成树模板)
题目描述
给出无向图中M个节点间N条边的权值。
求一个使得所有点连通的子图,要求图内的边权和最小
Input
测试输入包含若干测试用例
每个测试用例的第1行包含N、M ( <100 )
随后的 N 行每行包含3个数,边的起点,终点,权值
节点从1到M编号
当N为0时,全部测试结束.
Output
对每个测试用例,在1行里输出最小生成树权值。
若不存在符合要求的子图,则输出“?”。
Sample Input
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100
Sample Output
3
?
kruskal算法:
定理:任意一个最小生成树一定包含无向图中权值最小的那一条边。
所以给定一张无向图G = (V, E),n = V, m = E,先选出k条边构成一个生成森林,再从剩余的m-k条边中选出n - 1 - k添加到森林中,并且选出的边的权值之和最小.
kruskal算法从剩余的边中选出权值最小的,加入到森林中,图中节点的联通情况可用并查集维护
kruskal算法流程:
1.建立并查集,每个点各自构成一个集合
2.把所有的边按照权值从小到大排序,一次扫描每一条边
3.若x,y属于同一个集合,则忽略这条边,继续扫描下一条边
4.否则,合并x,y所在的集合,并将z累加到答案中
时间复杂度:O(m log(m)).
代码如下:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int f[200005];
struct p{int x, y, z;
}arr[200005];
bool cmp(p a, p b)
{return a.z < b.z;
}
int Find(int x)
{if(x != f[x])f[x] = Find(f[x]);return f[x];
}
int main()
{int n, m;cin >> n >> m;for(int i = 1; i <= n; i++)f[i] = i;for(int i = 0; i < m; i++){cin >> arr[i].x >> arr[i].y >> arr[i].z;}sort(arr, arr + m, cmp);int ans = 0, sum = 0;for(int i = 0; i < m; i++){int x = Find(arr[i].x);int y = Find(arr[i].y);if(x == y)continue;f[x] = y;sum++;ans += arr[i].z;if(sum == n - 1)break;}cout << ans << endl;return 0;
}
prim算法:
Prim算法的思想是:取图中任意一点作为起点放入树中,并向邻近树的点不断延伸,每次延伸的点要求满足到树的距离最短。
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#define Maxn 0x3f3f3f3f
using namespace std;
int arr[105][105];
int dis[105]; //记录每个结点间的最短距离
bool vis[105]; //判断该点是否被选过
int n ,m, ans;
void prim()
{memset(vis, false, sizeof vis);for(int i = 0; i <= n; i++)dis[i] = arr[1][i];dis[1] = 0;vis[1] = true;for(int i = 1; i < n; i++){int x = 0;for(int j = 1; j <= n; j++){if(!vis[j] && dis[j] < dis[x]){x = j;}}if(!x){cout << "?" << endl;return ;}vis[x] = true;ans += dis[x];for(int i = 1; i <= n; i++)if(!vis[i])dis[i] = min(dis[i], arr[x][i]);}cout << ans << endl;
}
int main()
{while(cin >> m >> n &&m){for(int i = 0; i <= n; i++)for(int j = 0; j <= n; j++)arr[i][j] = i == j? 0 : Maxn;int a, b, c;for(int i = 1; i <= m; i++){cin >> a >> b >> c;arr[a][b] = arr[b][a] = min(arr[a][b], c);}ans = 0;prim();}return 0;
}
prim算法之二叉堆优化,时间复杂度:O(m log(n))
代码如下:
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int arr[105][105];
int dis[105];
bool vis[105];
typedef pair<int ,int > p;
int main()
{int n, m;while(cin >> m >> n && m){for(int i = 0; i <= n; i++)for(int j = 0; j <= n; j++)arr[i][j] = i == j ? 0 : INF;memset(dis, INF, sizeof dis);memset(vis, false, sizeof vis);int a, b, c;for(int i = 0; i < m; i++){cin >> a >> b >> c;arr[a][b] = arr[b][a] = min(arr[a][b], c);}priority_queue<p, vector<p>, greater<p> > q;dis[1] = 0;int ans = 0, sum = 0;q.push({0, 1});while(q.size()){p cur = q.top();q.pop();int u = cur.second;if(vis[u])continue;vis[u] = true;sum++;ans += dis[u];for(int i = 1; i <= n; i++){if(!vis[i] && dis[i] > arr[u][i]){dis[i] = arr[u][i];q.push({dis[i], i});}}}if(sum == n)cout << ans << endl; //判断是否连通else cout << "?" << endl;}return 0;
}
畅通工程(最小生成树模板)相关推荐
- HDU 1863畅通工程(最小生成树)(prim算法)
畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- hdu1879 继续畅通工程 最小生成树
继续畅通工程 此题明显属于最小生成树的题目 关于最小生成树,有两种方法,一种是Kruskal方法,一种是Prim算法,第一种用并查集即可实现 1 /* 2 hdu1879 3 2013-03-18 1 ...
- hdu 1233 还是畅通工程 最小生成树(prim算法 + kruskal算法)
还是畅通工程 Time Limit: 4000/2 ...
- hdu 1879 继续畅通工程 (最小生成树)
继续畅通工程 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- HDU 1879 继续畅通工程 最小生成树
继续畅通工程 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description ...
- 还是畅通工程 最小生成树
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可 ...
- 畅通工程//最小生成树prim
题目: 畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- hdu 1879 继续畅通工程 最小生成树
继续畅通工程 Time Limit: 2000/ ...
- 题目1017:还是畅通工程(最小生成树初步应用)
题目链接:http://ac.jobdu.com/problem.php?pid=1017 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...
- HDU 1863 畅通工程 最小生成树
思路: 比较典型的最小生成树的题目了..在这里用求最小生成树的经典算法K(Kruskal)算法和P(Prim)算法.我的 K 算法用的是结构体来存图,P 算法用的是邻接矩阵来存图,K算法的复杂度是O( ...
最新文章
- 总结—elasticsearch启动失败的几种情况及解决
- SSM+BJUI实现CRUD的报表功能
- javascript数组的属性、方法和清空-最全!!!(必看)
- python的if语句例句_Python入门之if条件语句
- Activiti6记录
- Matlab调用Python函数,出现OSError: [WinError 126] 找不到指定的模块报错
- 图扑智慧交通:数字化地铁大屏管控运维平台
- 一个 Gitlab 帐号无法访问文件、克隆项目问题的解决
- On the Opportunities and Risks of Foundation Models- APPLICATIONS
- VMware虚拟机+Kali linux 2021.2 下载和安装以及初始操作
- 几何基础 罗德里格公式
- 【算法详解】splay的初步了解
- Cesium交流群链接
- 汽车之家搜索算法工程师招聘
- 《软技能-代码之外的生存指南》读书笔记
- Android 雷达图(蜘蛛网状图)
- Python3[爬虫实战] scrapy爬取汽车之家全站链接存json文件
- 防火墙导致web访问不到服务器解决方法
- TOOM舆情分析网络舆情监控平台研究现状
- Java项目:jsp房地产客户关系管理系统
热门文章
- mysql数据库主从复制部署笔记
- fltk在UbuntuLinux中搭建和测试-《C++程序设计原理与实践》Chapter12:显示模型 环境构建...
- OpenCV 离散傅里叶变换
- [Swift]LeetCode70. 爬楼梯 | Climbing Stairs
- EF中使用SQL语句或存储过程
- 第三周PLECS仿真实验
- 如何解决软键盘弹出引起的各种不适
- java 线程间的通讯(升级版)
- WinForm 的dataGridView全选,反选
- 深度学习入门读书笔记—全