最小生成树

最小生成树

≯℡__Kan透↙ 提交于 2020-04-08 14:48:23
1、什么是最小生成树? 我们可以知道一个有n个点n-1条边且无环的无向图一定是一棵树。 最小生成树就是在n个节点的 无向图中找到n-1条边构成一棵树且使这棵树的边权和最小。 2、怎么求? 1、Prim算法 这个算法在NOI中不常用( 不好用 ) 它的思想与Dijkstra算法相似,这里不再过多介绍 2、Kruskal算法 这才是我们的重点 它的思想是先把每条边按长度从小到大排好(快排) 然后从小到大用并查集的方法把没有"并"到一棵树上并入(在这个过程避免环的出现) 直到加入n-1条边后停止 #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n,m,ans; struct node{ int x,y,dis;//结构体定义起点终点边权 }a[10001]; int fa[10001],cnt; int Find(int x) { return fa[x]==x?x:fa[x]=Find(fa[x]); }//查 bool cmp(node a,node b) { return a.dis<b.dis; } int main() { int x,y; cin>>n>>m;//输入点数和边数 for(int i=1;i<=m;i++) cin>>a[i].x>>a[i].y>

最小生成树

青春壹個敷衍的年華 提交于 2020-04-04 17:44:17
有n个城市,给出了m条边,从m条边里面选n-1条边使得n个城市连通,且要求花费最小 样例输入: 6 9 (6个城市,9条边) 2 4 11 3 5 13 4 6 3 5 6 4 2 3 6 4 5 7 1 2 1 3 4 9 1 3 2 输出样例: 19 Kruskal算法: 适用于稀疏图 思想:将所有的边从大到小排序,再遍历所有边,如果该边的两个点不在同一个集合,那么将该边加入最小生成树,直到加入n-1条边 #include <stdio.h> #include <iostream> #include <algorithm> #include <vector> using namespace std; bool vis[105]; long long a[1005]; int n,m,c=0; long long ans; struct edge{ int u,v,w; }; edge e[105]; bool cmp(edge e1,edge e2){ //边的排序 return e1.w<e2.w; } int getf(int v){ //找祖先节点 if(a[v]==v){ return v; } else{ a[v]=getf(a[v]); return a[v]; } } int merge(int u,int v){ //判断是否将边加入最小生成树 int t1

并查集题目整理

若如初见. 提交于 2020-04-04 09:15:02
并查集 之前写最小生成树的时候对这一部分的知识也并没有十分详细的整理 近天做了一些用到并查集的题目,来整理一下 知识回顾 首先,先来回顾一下有关并查集的内容 <1> 定义 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。 集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的元素所在的集合合并。 <2>初始化 把每个点所在集合初始化为其自身。 通常来说,这个步骤在每次使用该数据结构时只需要执行一次,无论何种实现方式,时间复杂度均为O(N)。 <3>查找 查找元素所在的集合,即根节点。 <4>合并 将两个元素所在的集合合并为一个集合。 通常来说,合并之前,应先判断两个元素是否属于同一集合,这可用上面的"查找"操作实现。 主要处理的是有关这一部分的两个例题 Luogu P1550 [USACO08OCT]Watering Hole G 解题思路: 这个题给我的第一印象是最小生成树的Kruscal 但是仔细一读题发现其实有许多小的细节与最精简的Kruscal是有差别的 例如题目中有一个挖井的操作 那就讲问题拆开来看 part1:如何解决连牧场的操作 这里不难想到去直接最小生成树维护 很显然牧场之间的连线满足生成树的性质 part2:如何解决挖井的问题 考虑在不影响part1的前提下实现

数据结构和算法系列17 图

ε祈祈猫儿з 提交于 2020-04-03 11:49:52
数据结构和算法系列17 图 阅读目录 一,图的定义 二,图相关的概念和术语 三,图的创建和遍历 四,最小生成树和最短路径 五,算法实现 这一篇我们要总结的是图(Graph),图可能比我们之前学习的线性结构和树形结构都要复杂,不过没有关系,我们一点一点地来总结,那么关于图我想从以下几点进行总结: 1,图的定义? 2,图相关的概念和术语? 3,图的创建和遍历? 4,最小生成树和最短路径? 5,算法实现? 回到顶部 一,图的定义 什么是图呢? 图是一种复杂的非线性结构。 在线性结构中,数据元素之间满足唯一的线性关系,每个数据元素(除第一个和最后一个外)只有一个直接前趋和一个直接后继; 在树形结构中,数据元素之间有着明显的层次关系,并且每个数据元素只与上一层中的一个元素(双亲节点)及下一层的多个元素(孩子节点)相关; 而在图形结构中,节点之间的关系是任意的,图中任意两个数据元素之间都有可能相关。 图G由两个集合V(顶点Vertex)和E(边Edge)组成,定义为G=(V,E) 回到顶部 二,图相关的概念和术语 1,无向图和有向图 对于一个图,若每条边都是没有方向的,则称该图为无向图。图示如下: 因此,(V i ,V j )和(V j, V i )表示的是同一条边。注意, 无向图是用小括号,而下面介绍的有向图是用尖括号。 无向图的顶点集和边集分别表示为: V(G)={V 1 ,V 2 ,V

数据结构

烈酒焚心 提交于 2020-04-03 11:48:27
一,图的定义 什么是图呢? 图是一种复杂的非线性结构。 在线性结构中,数据元素之间满足唯一的线性关系,每个数据元素(除第一个和最后一个外)只有一个直接前趋和一个直接后继; 在树形结构中,数据元素之间有着明显的层次关系,并且每个数据元素只与上一层中的一个元素(双亲节点)及下一层的多个元素(孩子节点)相关; 而在图形结构中,节点之间的关系是任意的,图中任意两个数据元素之间都有可能相关。 图G由两个集合V(顶点Vertex)和E(边Edge)组成,定义为G=(V,E) 回到顶部 二,图相关的概念和术语 1,无向图和有向图 对于一个图,若每条边都是没有方向的,则称该图为无向图。图示如下: 因此,(V i ,V j )和(V j, V i )表示的是同一条边。注意, 无向图是用小括号,而下面介绍的有向图是用尖括号。 无向图的顶点集和边集分别表示为: V(G)={V 1 ,V 2 ,V 3 ,V 4 ,V 5 } E(G)={(V 1 ,V 2 ),(V 1 ,V 4 ),(V 2 ,V 3 ),(V 2 ,V 5 ),(V 3 ,V 4 ),(V 3 ,V 5 ),(V 4 ,V 5 )} 对于一个图G,若每条边都是有方向的,则称该图为有向图。图示如下。 因此,<V i ,V j >和<V j, V i >是两条不同的有向边。注意,有向边又称为弧。 有向图的顶点集和边集分别表示为: V(G)

数据结构和算法系列-------- 图

眉间皱痕 提交于 2020-04-03 11:47:50
原文地址 http://www.cnblogs.com/mcgrady/archive/2013/09/23/3335847.html#_label2 阅读目录 一,图的定义 二,图相关的概念和术语 三,图的创建和遍历 四,最小生成树和最短路径 五,算法实现 这一篇我们要总结的是图(Graph),图可能比我们之前学习的线性结构和树形结构都要复杂,不过没有关系,我们一点一点地来总结,那么关于图我想从以下几点进行总结: 1,图的定义? 2,图相关的概念和术语? 3,图的创建和遍历? 4,最小生成树和最短路径? 5,算法实现? 一,图的定义 什么是图呢? 图是一种复杂的非线性结构。 在线性结构中,数据元素之间满足唯一的线性关系,每个数据元素(除第一个和最后一个外)只有一个直接前趋和一个直接后继; 在树形结构中,数据元素之间有着明显的层次关系,并且每个数据元素只与上一层中的一个元素(双亲节点)及下一层的多个元素(孩子节点)相关; 而在图形结构中,节点之间的关系是任意的,图中任意两个数据元素之间都有可能相关。 图G由两个集合V(顶点Vertex)和E(边Edge)组成,定义为G=(V,E) 二,图相关的概念和术语 1,无向图和有向图 对于一个图,若每条边都是没有方向的,则称该图为无向图。图示如下: 因此,(V i ,V j )和(V j, V i )表示的是同一条边。注意, 无向图是用小括号

最小生成树(模板+入门题)

点点圈 提交于 2020-04-02 23:39:38
最小生成树 加权图是一种为每条边关联一个权值(可表示成本、时间等)的图模型。这种图能表示许多场景,如航空图中边表示航线,权值表示距离或费用。在航空图中,通常的问题是如何使距离或费用最小化。 我们可以通过加权无向图的最小生成树来解决这个问题。 图的生成树:是它的一颗含有其他所有顶点的无环连通子图。一幅加权无向图的最小生成树(MST)是它的一颗权值最小的生成树(树中所有边的权值之和最小)。 我们会一起学习计算最小生成树的两种经典算法:Prime算法和Kruskal算法。 首先有几个注意点: 只考虑连通图 边的权值可以表示距离、时间、费用或其他变量 边的权重可能是0或负数 所有边的权重都不相同 我们要在一幅加权连通无向图中找到它的最小生成树。 首先定义一下 加权无向图的数据结构 最小生成树算法:Prim算法和Kruskal算法 Prim算法: Prim算法 模板: 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include

最小生成树

可紊 提交于 2020-03-28 00:32:36
最小生成树 模板 Prim Kruskal 例题 走廊泼水节 https://ac.nowcoder.com/acm/contest/1056/A 题意 将一棵树加不同权值的边,变成一个完全图,问加的权值和最小为多少? 思路 推论:对于两棵树,要在两棵树之间选择一条边,仍然是最小生成树,必然是选择两棵树之间权值最小的边 考虑Kruskal的建树方式 本题从也从最短的边开始计算 代码 : https://xlorpaste.cn/tjw8rk 来源: https://www.cnblogs.com/guaguastandup/p/12585251.html

HDU 1102 最小生成树 prim

情到浓时终转凉″ 提交于 2020-03-26 07:54:17
http://acm.hdu.edu.cn/showproblem.php?pid=1102 最小生成树 (prim) 代码: #include<cstdio>#include<iostream>const int inf=1002;using namespace std;int a[101][101],dis[101],visit[101];int prim(int N)//1为原点{ int i,sum,min,mark,j,k; for(i=2;i<=N;i++) dis[i]=a[1][i]; dis[1]=0; visit[1]=1; sum=0; for(i=1;i<N;i++) { min=inf; for(k=1;k<=N;k++) { if(visit[k]==0&&min>dis[k]) { mark=k; min=dis[k]; } } sum+=min; visit[mark]=1; dis[mark]=0; for(j=1;j<=N;j++) { if(dis[j]>dis[mark]+a[mark][j]&&visit[j]==0) dis[j]=dis[mark]+a[mark][j]; } } return sum;}int main(){ int N,i,j,Q; while(scanf("%d",&N)!=EOF) { for(i=1;i<=N

hdu1102(最小生成树)

戏子无情 提交于 2020-03-26 07:53:27
题意为将所有点连起来,但是有些边已经帮你连好了,要求你将剩下的连起来形成最小生成树。 因为一些点已经连起来了,所以应该选用kruskal算法。虽然这道题的图是按照邻接矩阵给出的,但选用prim算法的话,实现起来反而不容易还容易出错,倒不如自己对输入进行一些加工,然后选取kruskal算法。 #include <iostream> #include <stdio.h> #include <queue> using namespace std; int input[105][105]; int N; int parent[105]; struct Edge { int s,e,w; Edge(int ss,int ee,int ww):s(ss),e(ee),w(ww){} Edge(){} bool friend operator<(Edge n1,Edge n2) { return n1.w>n2.w; } }; int findP(int x) { if(x==parent[x]) return x; else return parent[x]=findP(parent[x]); } void Union(int x,int y) { int xp=findP(x),yp=findP(y); parent[yp]=xp; } void kruskal() { int ans=0;