最小生成树

HDU--1301--构图+最小生成树

夙愿已清 提交于 2020-02-25 00:35:26
The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money was spent on extra roads between villages some years ago. But the jungle overtakes roads relentlessly, so the large road network is too expensive to maintain. The Council of Elders must choose to stop maintaining some roads. The map above on the left shows all the roads in use now and the cost in aacms per month to maintain them. Of course there needs to be some way to get between all the villages on maintained roads, even if the route is not as short as before. The Chief Elder would like to tell the

最小生成树--prim--Networking

岁酱吖の 提交于 2020-02-23 15:35:21
最小生成树–prim–Networking Description You are assigned to design network connections between certain points in a wide area. You are given a set of points in the area, and a set of possible routes for the cables that may connect pairs of points. For each possible route between two points, you are given the length of the cable that is needed to connect the points over that route. Note that there may exist many possible routes between two given points. It is assumed that the given possible routes connect (directly or indirectly) each two points in the area. Your task is to design the network for the

最小生成树--prim算法

江枫思渺然 提交于 2020-02-22 15:14:28
最小生成树–prim算法 应用背景: 最节省经费的前提下,在n个城市之间建立通信联络网 定点表示城市 边表示城市之间的线路 边的权值表示相应的代价 生成树的代价:树上各边权值之和 最小代价生成树(Minimum Cost Spanning Tree , 简称最小生成树) 无相连通网的最小代价生成树 左边的就是连通图,右边的就是最小代价生成树 一个连通图的最小生成树不一定唯一,但最小生成树的代价(权值之和)一定是相同的 构造最小生成树有多种算法,其中多数利用了最小生成树的MST性质 在这个图中我们去任意划分这个图的两个集合,一定存在某个边跨越这两个数的集合,这条边一定是在我们最小生成树上面 MST性质 树的概念:只要在树的任意一条加上一条边,一定会产生回路 Prim算法 closedge数组 附设一个辅助数组closedge,用记录从V-U的各个顶点到U的具有最小代价的边 对每个顶点vi属于V - U , 相应的分量为closedge [ i - 1 ] , 它包括两个域: 1. lowcost存储该边上的权,即 closedge [ i - 1 ] . lowcost = min { cost ( u , vi ) | u∈U } 网用领接矩阵表示法 2. Adjvex存储该边依附的在U中的顶点 U中每增加一个顶点,只要考虑该新增顶点到vi的这条边上的权值会不会更小即可 来源:

普里姆算法与修路问题

橙三吉。 提交于 2020-02-22 12:07:46
应用场景-修路问题 看一个应用场景和问题: 有胜利乡有7个村庄(A, B, C, D, E, F, G) ,现在需要修路把7个村庄连通 各个村庄的距离用边线表示(权) ,比如 A – B 距离 5公里 问:如何修路保证各个村庄都能连通,并且总的修建公路总里程最短? 最小生成树 修路问题本质就是就是最小生成树问题, 先介绍一下最小生成树 (Minimum Cost Spanning Tree),简称MST。 给定一个带权的无向连通图,如何选取一棵生成树,使树上所有 边上权的总和为最小 ,这叫最小生成树 N个顶点,一定有N-1条边 包含全部顶点 N-1条边都在图中 举例说明(如图:) 求最小生成树的算法主要是 普里姆 算法和克鲁斯卡尔算法 思路: 将10条边,连接即可,但是总的里程数不是最小. 正确的思路 ,就是尽可能的选择少的路线,并且每条路线最小,保证总里程数最少. 普里姆算法介绍 普利姆(Prim)算法求最小生成树,也就是在包含n个顶点的连通图中,找出只有(n-1)条边包含所有n个顶点的连通子图,也就是所谓的 极小连通子图 普利姆的算法如下: 设G=(V,E)是连通网,T=(U,D)是最小生成树,V,U是顶点集合,E,D是边的集合 若从顶点u开始构造最小生成树,则从集合V中取出顶点u放入集合U中,标记顶点v的visited[u]=1 若集合U中顶点ui与集合V

最小生成树(模板 prim)

我的未来我决定 提交于 2020-02-22 11:08:17
Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表, 表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。 Input 测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示 未建。 当N为0时输入结束。 Output 每个测试用例的输出占一行,输出全省畅通需要的最低成本。 Sample Input 3 1 2 1 0 1 3 2 0 2 3 4 0 3 1 2 1 0 1 3 2 0 2 3 4 1 3 1 2 1 0 1 3 2 1 2 3 4 1 0 Sample Output 3 1 0 代码如下: 1 # include<iostream> 2 # include<cstdio> 3 # include<cstring> 4 # include<algorithm> 5 using namespace std; 6 const int INF=1<<28; 7 int mp[105][105]

算法培训 Day4-3 最小生成树

人走茶凉 提交于 2020-02-21 11:36:59
算法培训 Day4-3 最小生成树 两种做法 Kruscal 和 Prim 1.Kruscal 虽然这个适合稀疏图,但好像没怎么遇到边很多的图,就算边很多,因为是遍历一遍边 即O(n) 复杂度,但是因为要先排序 所以总的复杂度为 mlogm 也是很快速算完的, 且经过对比 比Prim 耗时还要短 需要用sort对边的结构体进行排序 struct edge{ int u,v; long long len; }e[maxm]; bool cmp(edge &e1,edge &e2){ return e1.len < e2.len; } 然后需要使用并查集 且需要路径压缩 (现在不怎么看的懂了 但是代码很简洁 就直接记下来吧) int fa[maxn]; int find(int x) { return fa[x] == x? x : fa[x]=find(fa[x]); } 下面就是 算法核心 每次选取最短的边 已经排好序 void Kruscal ( ) { for ( int i = 1 ; i <= n ; i ++ ) fa [ i ] = i ; for ( int i = 1 ; i <= m ; i ++ ) { int tempu = e [ i ] . u , tempv = e [ i ] . v ; int fau = find ( tempu ) , fav =

C数据结构与算法-基础整理-图-06:克鲁斯卡尔算法详解

对着背影说爱祢 提交于 2020-02-19 04:08:47
详解最小生成树中的克鲁斯卡尔算法 0x01.关于克鲁斯卡尔算法 Kruskal算法 是一种用来查找 最小生成树 的算法,由Joseph Kruskal在1956年发表。克鲁斯卡尔算法主要针对边集数组展开。 0x02.基础代码 这个算法主要是针对边集数组,先来看一下边集数组的结构: //边集数组 typedef struct { int begin; int end; int weight; }Edge; 通常用到邻接矩阵,所以还需要由邻接矩阵转化为边集数组。另外这个算法还需要按照边的权值升序排序。 void OperationEdge(Graph G, Edge* edges) { int i, j,k; k = 0; for (i = 0; i < G.numv; i++) { for (j = i+1; j < G.numv; j++)//只需要转化邻接矩阵的一半,无向图 { if (G.edge[i][j] != INTMAX && G.edge[i][j] != 0) { edges[k].begin = i; edges[k].end = j; edges[k].weight = G.edge[i][j]; k++; } } } for (i = 0; i < k-1; i++)//简单交换排序 { for (j = i + 1; j < k; j++) { if

最小生成树prim和kruskal模板

我是研究僧i 提交于 2020-02-17 18:37:50
prim: int cost[MAX_V][MAX_V]; //cost[u][v]表示边e=(u,v)的权值(不存在的情况下设为INF) int mincost[MAX_V]; //从集合X出发的每个变得最小权值 bool used[MAX_V]; //顶点i是包含在集合X中 int V; //顶点数 int prim() { int res = 0; for(int i=0;i < V;i++) { mincost[i] = INF; used[i] = false; } mincost[0] = 0; while(1) { int v = -1; for(int u=0;u < V;u++) //从点集外找权值最小的路径 { if(!used[u]&&(v == -1 || mincost[u] < mincost[v])) //因为c++从左到右所以这样写不会越界 v = u; } if(v == -1) break; used[v] = true; res += mincost[v]; //把每次的权值加上去 for(int u=0;u < V;u++) //因为新把 v 加入点集,因此Mincost[]需要重新计算 { mincost[u] = min(mincost[u],cost[v][u]); } } return res; } kruskal + 并查集:

Freckles(Kruskal解决最小生成树问题)——C++实现

放肆的年华 提交于 2020-02-16 23:34:11
题目链接: https://www.nowcoder.com/practice/41b14b4cd0e5448fb071743e504063cf?tpId=40&tqId=21371&tPage=1&rp=1&ru=/ta/kaoyan&qru=/ta/kaoyan/question-ranking 代码如下: #include <bits/stdc++.h> using namespace std; const int MAXN=101; struct Point{ double x; double y; int order;//作为点的序号,以便使用并查集 };//点结构体 struct Edge{ Point from;//起点 Point to;//终点 double distance;//距离 bool operator< (const Edge e) const{ return distance<e.distance; } };//边结构体 Edge edge[MAXN*MAXN];//边集 int father[MAXN];//父节点 int height[MAXN];//节点高度 void Initial(int n){ //初始化 for(int i=0;i<=n;i++){ father[i]=i; height[i]=0; } } int Find(int x

[noi.ac] #31 最小生成树

你。 提交于 2020-02-15 23:51:45
问题描述 小 \(D\) 最近学习了最小生成树的有关知识。为了更好地学习求最小生成树的流程,他造了一张 \(n\) 个点的带权无向完全图(即任意两个不同的点之间均有且仅有一条无向边的图),并求出了这个图的最小生成树。 为了简单起见,小 \(D\) 造的无向图的边权为 \([1,\frac{n(n-1)}{2}]\) 之间的整数,且任意两条边的边权均不一样。 若干天后,小 \(D\) 突然发现自己不会求最小生成树了。于是他找出了当时求出的最小生成树,但是原图却怎么也找不到了。于是小 \(D\) 想要求出,有多少种可能的原图。但是小 \(D\) 连最小生成树都不会求了,自然也不会这个问题。请你帮帮他。 形式化地,你会得到 \(n-1\) 个递增的正整数 \(a_1,a_2,\cdots,a_{n-1}\) ,依次表示最小生成树上的边的边权。你要求出,有多少张 \(n\) 个点的带权无向完全图,满足: 每条边的边权为 \([1,\frac{n(n-1)}{2}]\) 之间的整数; 任意两条不同的边的边权也不同; 至少存在一种最小生成树,满足树上的边权按照从小到大的顺序排列即为 \(a_1,a_2,\cdots,a_{n-1}\) (事实上,可以证明任意一张无向图的任意两棵最小生成树上的边权集合相同)。 因为答案可能很大,所以你只要求出答案对 \(10^9+7=1,000,000,007\