最小生成树 洛谷P3366【模板】最小生成树 洛谷P2820 局域网
嗯...
理解生成树的概念:
在一幅图中将所有n个点连接起来的n-1条边所形成的树。
最小生成树:
边权之和最小的生成树。
最小瓶颈生成树:
对于带权图,最大权值最小的生成树。
如何操作?
1.Prim算法(O(mlogn))
2.Kruskal算法(O(mlogn))
推荐使用第二种,无需建图。
算法流程:
Prim算法:(思想类似dijkstra)
随意选取一个点作为已访问集合的第一个点,并将所有相连的边加入堆中
从堆中找到最小的连接集合内和集合外点的边,将边加入最小生成树中
将集合外点标记为已访问,并将相连边加入堆
重复以上过程直到所有点都在访问集合中
Kruskal算法:(并查集思想)
将边按照权值排序
依次枚举每一条边,若连接的两点不连通则加入最小生成树中
使用并查集维护连通性
模板代码:
1 int f[101], h; 2 struct node{ 3 int x, y, l; 4 } a[100001]; 5 inline bool cmp(node i, node j){ 6 return i.l < j.l; 7 } 8 inline int find(int x){ 9 if(x != f[x])//本身是否为父亲节点 10 f[x] = find(f[x]); 11 return f[x]; 12 }//并查集操作 13 int main(){ 14 for(int i = 1; i <= n; i++){ 15 f[i] = i; 16 }//父节点初始化 17 sort(a+1, a+k+1, cmp);//排序 18 for(int i = 1; i <= k; i++){ 19 int r1 = find(a[i].x); 20 int r2 = find(a[i].y); 21 if(r1 != r2){ 22 f[r1] = r2; 23 } 24 } 25 }
Kruskal
#include<bits/stdc++.h> using namespace std; int n,m,a,b,c; int sum; int g[1001][1001],minn[1001]; bool u[1001]; int main(){memset(g,0x7f,sizeof(g));memset(minn,0x7f,sizeof(minn));memset(u,true,sizeof(u));cin>>n>>m;for(int i=1;i<=m;i++){cin>>a>>b>>c;g[a][b]=g[b][a]=c;sum+=c;}minn[1]=0;for(int i=1;i<=n;i++){int k=0;for(int j=1;j<=n;j++)if(u[j]&&minn[j]<minn[k])k=j; u[k]=false;for(int j=1;j<=n;j++)if(u[j]&&g[k][j]<minn[j])minn[j]=g[k][j];}int total=0;for(int i=1;i<=n;i++) total+=minn[i];cout<<sum-total<<endl;return 0; }
Prim
模板题:
洛谷P3366【模板】最小生成树:
题目链接:https://www.luogu.org/problemnew/show/P3366
思路:(Kruskal)
一道模板题,首先用一个结构体读入,然后初始化父节点,再按边权排序,然后用find函数分别找输入时的两个点的父节点,并判断其中一个是否是另一个的父亲,否则就进行合并,并将h+=a[i].l。(思路比较好理解)
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 5 using namespace std; 6 7 int h, f[200005]; 8 9 struct node{ 10 int x, y, l; 11 } a[200005]; 12 13 inline bool cmp(node i, node j){ 14 return i.l < j.l; 15 } 16 17 inline int find(int x){ 18 if(x != f[x]) 19 f[x] = find(f[x]); 20 return f[x]; 21 } 22 23 int main(){ 24 int n, m; 25 scanf("%d%d", &n, &m); 26 for(int i = 1; i <= n; i++){ 27 f[i] = i; 28 } 29 for(int i = 1; i <= m; i++){ 30 scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].l); 31 //h += a[i].l; 32 } 33 sort(a+1, a+m+1, cmp); 34 for(int i = 1; i <= m; i++){ 35 int r1 = find(a[i].x); 36 int r2 = find(a[i].y); 37 if(r1 != r2){ 38 f[r1] = r2; 39 h += a[i].l; 40 //h -= a[i].l; 41 } 42 } 43 printf("%d", h); 44 return 0; 45 }
AC代码
洛谷P2820 局域网:
题目链接:https://www.luogu.org/problemnew/show/P2820
思路:
首先这道题的问法就很模板:
很显然“f(i,j)表示i,j之间连接的畅通程度”即为i到j点的权值;“除去一些连线,使得网络中没有回路,并且被除去网线的Σf(i,j)最大”很显然是求最小生成树。但注意一个细节,它与最小生成树有所不同,它要求的是Σf(i,j)最大。
所以我们在最小生成树的模板上进行修改即可:读入时将所有的边权都加到h中。在判断父节点是否相同时,若不同,则将合并,并将合并的这条边的权值减掉即可。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 5 using namespace std; 6 7 int f[101], h; 8 9 struct node{ 10 int x, y, l; 11 } a[100001]; 12 13 inline bool cmp(node i, node j){ 14 return i.l < j.l; 15 } 16 17 inline int find(int x){ 18 if(x != f[x]) 19 f[x] = find(f[x]); 20 return f[x]; 21 } 22 23 int main(){ 24 int n, k; 25 scanf("%d%d", &n, &k); 26 for(int i = 1; i <= n; i++){ 27 f[i] = i; 28 } 29 for(int i = 1; i <= k; i++){ 30 scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].l); 31 h += a[i].l; 32 } 33 sort(a+1, a+k+1, cmp); 34 for(int i = 1; i <= k; i++){ 35 int r1 = find(a[i].x); 36 int r2 = find(a[i].y); 37 if(r1 != r2){ 38 f[r1] = r2; 39 h -= a[i].l; 40 } 41 } 42 printf("%d", h); 43 return 0; 44 }
AC代码
大概就是这样,个人认为Kruskal算法比Prim算法写起来简单并好理解....
转载于:https://www.cnblogs.com/New-ljx/p/10779353.html
最小生成树 洛谷P3366【模板】最小生成树 洛谷P2820 局域网相关推荐
- 最小生成树的两个模板
什么是最小生成树??当在一个图中,这个图描绘了节点与节点的关系,表现为这个节点到下一个节点的 "代价" 那么我们想把这个图中的各个节点用最小的代价连接起来该怎么办呢??这里就要知道 ...
- 角谷猜想:所谓角谷猜想,是指对于任意一个正整数,如果是奇数,则乘 3 加 1,如果是偶数,则除以2,得到的结果再按照上述规则重复处理,最终总能够得到 1。如假定初始整数为 5,计算过程分别为 16、
角谷猜想 Description 所谓角谷猜想,是指对于任意一个正整数,如果是奇数,则乘 3 加 1,如果是偶数,则除以2,得到的结果再按照上述规则重复处理,最终总能够得到 1.如,假定初始整数为 5 ...
- 阿米洛键盘失灵_阿米洛 海韵评测:可爱的键帽,强大的轴型,少女心十足!...
今日话题:阿米洛 海韵评测:可爱的键帽,强大的轴型,少女心十足! 前几天小编在网上发现一款非常好看的阿米洛键盘,大家都知道阿米洛键盘的外观在所有机械键盘中可谓是做的最好的几种之一.所以小编今天就给大家 ...
- 剑灵双线西洛区服务器位置,剑灵西洛区将开启 西洛新的挑战福利等你来参与...
原标题:剑灵西洛区将开启 西洛新的挑战福利等你来参与 为了迎接 剑灵全新大区西洛区1月17日开启,官方为玩家准备了海量升级签到福利.那么 剑灵西洛新的挑战福利有哪些?下面就来看看剑灵西洛新的挑战福利介 ...
- 洛谷U4807抽水机[最小生成树]
题目背景 kkk被Farmer John和他的奶牛贝茜虐的很惨,然后她也想体验下一个Farmer的生活.但她又懒得种地,就选择养鱼. 题目描述 这些鱼都是热带鱼(废话),很娇贵(比kkk娇贵),要经常 ...
- 洛谷 P4208 [JSOI2008]最小生成树计数 矩阵树定理
题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的).由于不同的 ...
- BZOJ1016 || 洛谷P4208 [JSOI2008]最小生成树计数【矩阵树定理】
时空限制 1000ms / 128MB 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则 ...
- 专题·树链剖分【including 洛谷·【模板】树链剖分
初见安~~~终于学会了树剖~~~ [兴奋]当初机房的大佬在学树剖的时候我反复强调过:"学树剖没有前途的!!!" 恩.真香. 一.重链与重儿子 所谓树剖--树链剖分,就是赋予一个链的 ...
- 洛谷·【模板】点分树 | 震波【including 点分树
初见安-这里是传送门:洛谷P6329 [模板]点分树 | 震波 一.点分树 其实你会点分治的话,点分树就是把点分治时的重心提出来重新连城一棵树. 比如当前点是u,求出子树v的重心root后将root与 ...
最新文章
- 解读《德勤2017年全球CIO报告》:顶级CIO的炼成之道
- 《LeetCode力扣练习》第7题 C语言版 (做出来就行,别问我效率。。。。)
- java io使用哪些设计模式_JAVA IO中的设计模式
- 阅读作业二:团队项目与测试工作
- [py2neo]Ubuntu14 安装py2neo失败问题解决
- ASP.NET2.0中配置文件的加密与解密
- c语言整数与平均值,编写求一组整数的和与平均值的程序
- gitter 卸载_最佳Gitter渠道:开发人员工具
- 【FZU - 2254】英语考试(最小生成树,思维,建图)
- ubuntu麒麟下安装并启用搜狗输入法
- JQuery文件上传插件ajaxFileUpload在Asp.net MVC中的使用[转载]
- kafka 新加入副本_Apache-Kafka 核心组件和流程-控制器
- 一位博士在华为的 22 年(干货满满)
- openrasp-iast 灰盒扫描工具
- android 使用adb命令安装安卓apk包
- ArduinoUNO实战-第十四章-LM35温度传感器和DS18B20温度传感器
- 《百家讲坛》之战国七雄
- python Shapely使用指南详解
- windows环境系安装flask框架,pyth3.x版本
- Maple: 矩阵转置
热门文章
- AC自动机 - 多模式串的匹配 --- HDU 3695 Computer Virus on Planet Pandora
- 4月电脑分辨率TOP10 :仅亚军1920*1080占比上涨
- tomcat报错“The specified JRE installation does not exist”
- Ruby on Rails Exception:Routing Error
- VMWARE虚拟机中CentOs7网络连接
- git 安装 on centos7
- 林洋能源:布局能源互联网 分布式光伏龙头再扬帆
- 使用.NET Framework的配置文件app.config
- 就像教育一样,本身作用巨大,当过度强化,就是扭曲了~
- Hadoop配置项整理(hdfs-site.xml)