最小生成树

HDU1102--最小生成树

∥☆過路亽.° 提交于 2020-03-26 07:53:10
Constructing Roads Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9149 Accepted Submission(s): 3383 Problem Description There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected. We know that there are already some roads between some villages and your job is the build some

hdu1102 最小生成树

孤者浪人 提交于 2020-03-26 07:52:51
本题本是模板题,但由于开始并查集写出,好不容易发现了,有没改彻底,导致狂WA,以后一定要注意,修改后要多检查,别急忙交; #include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #define maxn 105 using namespace std; const int INF = 0x3f3f3f; int G[maxn][maxn]; struct Edge{ int from; int to; int len; bool operator <(const Edge& rh) const { return len < rh.len ; } }; struct MST{ int n; int m; Edge edge[maxn*maxn]; int p[maxn]; void init(int num){ m = 0; n = num; for(int i=0;i<n;i++) p[i] = i; } int find(int x){ return p[x]==x ? x : p[x] = find(p[x]); } void Addedge(int i,int j,int len){ edge[m].from = i; edge[m].to = j; edge[m].len =

贪心算法(2)-Kruskal最小生成树

坚强是说给别人听的谎言 提交于 2020-03-19 09:08:21
什么是最小生成树? 生成树是相对图来说的,一个图的生成树是一个树并把图的所有顶点连接在一起。一个图可以有许多不同的生成树。一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。最小生成树其实是 最小权重生成树 的简称。生成树的权重是考虑到了生成树的每条边的权重的总和。 最小生成树有几条边? 最小生成树有(V – 1)条边,其中V是给定的图的顶点数量。 Kruskal算法 下面是步骤寻找MST使用Kruskal算法 1 1,按照所有边的权重排序(从小到大) 2 3 2,选择最小的边。检查它是否形成与当前生成树形成环。如果没有形成环,讲这条边加入生成树。否则,丢弃它。 4 5 3,重复第2步,直到有生成树(V-1)条边 步骤2使用 并查集算法 来检测环。如果不熟悉并查集建议阅读下 并查集 。 该算法是一种贪心算法。贪心的选择是选择最小的权重的边,并不会和当前的生成树形成环。让我们了解一个例子,考虑下面输入图 spanning-tree-mst 该图包含9个顶点和14个边。因此,形成最小生成树将有(9 – 1)= 8条边。 01 排序后: 02 Weight Src Dest 03 1 7 6 04 2 8 2 05 2 6 5 06 4 0 1 07 4 2 5 08 6 8 6 09 7 2 3 10 7 7 8 11 8

最小生成树MST

若如初见. 提交于 2020-03-14 12:45:04
Description 生成树:一个有n个结点的连通图的生成树是原图的极小连通子图,包含原图中的所有n个结点,并且有保持图连通的最少的边。 最小生成树:生成树中权值最小的一种方案。 给定一个无向图,请输出最小生成熟的权值。 存在重边 Input 第一行包含三个整数N、M,分别表示点的个数、边的个数; 接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条边的两个点和长度。 Output 输出最小生成熟的权值,如果答案不存在,请输出-1。 Sample Input 4 6 1 2 2 2 3 2 2 4 1 1 3 5 3 4 3 1 4 4 Sample Output 5 Hint 对于100%的数据:N<=1000,M<=400000 Source #include <bits/stdc++.h> using namespace std; int n,m; struct point { int a,b,val; }; point p[400001]; int f[1001]; bool cmp(point x,point y) { return x.val<y.val; } int find(int x) { if(x==f[x]) return x; f[x]=find(f[x]); return f[x]; } int main() { cin>>n>>m; for

最小生成树prim算法(模板)

我是研究僧i 提交于 2020-03-14 03:48:52
prim算法适合稠密图,即边数较多而点较少的情况,时间复杂度为 O ( n 2 ) O ( n 2 ) ,堆优化的情况下,如果点数为m,边数为n,可以达到 O ( n l o g m ) O ( n l o g m ) .思想很简单,就是每次寻找一条由已加入集合的点和与它们相邻的没加入集合的点的权值最小边,进行n-1次就找出来了,也是贪心的思想,实现就是随便找一个初始节点,然后建一个最小堆(边小的先pop出来),把该节点的vis值置为1,遍历该节点相邻的节点,如果没有被vis标记过,就加入边到堆中,扫完了以后处理堆中数据,如果弹出的边被标记过就pop,没有就取出来,把边通往的节点置为key,下次就加入key节点有关没有标记过的边。循环n-1次,把每一次堆弹出边的值累加起来就是最小生成树的值了 #include<bits/stdc++.h> using namespace std; const int maxn=1005; struct Edge{ int to,dist; Edge(int t,int d):to(t),dist(d){} bool operator<(const Edge& e)const{ return dist>e.dist; } }; int n,m; bool vis[maxn]; vector<Edge> g[maxn]; priority_queue

最小生成树(Prim算法)

亡梦爱人 提交于 2020-03-12 13:33:10
Prim算法 先选择一个点作为起始,然后每次找权值离这些点最小的,直到所有点找到,此算法如同“生长树”一样,慢慢长大,从1个顶点到n个顶点。 例如:首先选择了1号点开始,每一步都选择离树最近的点相连接,直到连接完毕。 思路: 1.任意选择一点开始构造生成树,并用数组标记那些点已经加入了生成树中 2.在用数组记录生成树到各个顶点的距离,一开始即其他点到这个起始点的距离(2.3.操作类似于Dijkstra算法) 3.从数组中选出离生成树最近的点加入到生成树中,再根据这个点松弛距离数组 4.重复第三步,直到生成树完毕 Prim算法核心代码: //vis数组标记是否加入生成树,dis数组标记各点到生成树的距离,e为邻接矩阵 while ( count < n ) { min = inf ; //寻找最近的点,loc记录位置 for ( i = 1 ; i <= n ; i ++ ) if ( vis [ i ] == 0 && dis [ i ] < min ) { min = dis [ i ] ; loc = i ; } vis [ loc ] = 1 ; count ++ ; sum + = dis [ loc ] ; //loc点的所有出边,如果通过loc中转能缩短距离,则松弛 for ( i = 1 ; i <= n ; i ++ ) if ( vis [ i ] == 0 &&

最小生成树算法——kruskal

风流意气都作罢 提交于 2020-03-08 16:38:35
如图,输出最小生成树的生成过程 算法思想: 每个边的权值进行从小到大排序 然后从小到大添加到最小生成树中,若添加一个边后构成环路,则此边不能添加。直到每个顶点都加入到最小生成树中。 需要一个结构体来存储 每个边的权值与始末顶点。再进行排序。 struct { VexType head ; VexType tail ; ArcType lowcost ; } Edge [ MAXSIZE ] ; //存入每条边的首尾以及权值 通过无向图写出邻接矩阵,调用函数创建邻接矩阵 VexType vexs [ 7 ] = { '0' , '1' , '2' , '3' , '4' , '5' , '6' } ; ArcType arcs [ 7 ] [ 7 ] = { { 0 , 17 , MAXNUM , MAXNUM , MAXNUM , 10 , MAXNUM } , { 17 , 0 , 16 , MAXNUM , MAXNUM , MAXNUM , 14 } , { MAXNUM , 16 , 0 , 12 , MAXNUM , MAXNUM , MAXNUM } , { MAXNUM , MAXNUM , 12 , 0 , 19 , MAXNUM , 18 } , { MAXNUM , MAXNUM , MAXNUM , 19 , 0 , 25 , 24 } , { 10 ,

Slim Span (最小生成树)

我怕爱的太早我们不能终老 提交于 2020-03-08 09:36:04
题意 求生成树的最长边与最短边的差值的最小值 题解 最小生成树保证每一条边最小,就只要枚举最小边开始,跑最小生成树,最后一个值便是最大值 在枚举最小边同时维护差值最小,不断更新最小值。 C++代码 /** /*@author Victor /*language C++ */ #include <bits/stdc++.h> #include<iostream> #include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<bitset> #include<queue> #include<deque> #include<stack> #include<cmath> #include<list> #include<map> #include<set> //#define DEBUG #define RI register int using namespace std; typedef long long ll; //typedef __int128 lll; const int N=100000+10; const int MOD=1e9+7; const double PI = acos(-1.0); const

【最小生成树】kruskal模板 prim模板

混江龙づ霸主 提交于 2020-03-04 22:08:03
kruskal #include <bits/stdc++.h> using namespace std; const int maxx=0x3f3f3f3f; const int maxn=10000; struct node { int u,v,l; bool operator <(const node &a)const { return l<a.l; } }edge[maxn]; int father[maxn]; int nodenum,edgenum; void init() { for(int i=0;i<nodenum;i++) { father[i]=i; } } int Find(int x) { if(x==father[x])return x; return father[x]=Find(father[x]); } void Union(int x,int y) { int temp_x=Find(x); int temp_y=Find(y); if(temp_x!=temp_y) { father[temp_x]=temp_y; } } int kruskal() { sort(edge,edge+edgenum); init(); node now; int ans=0; for(int i=0;i<edgenum;i++) { now=edge[i];

Boruvka最小生成树模板

纵然是瞬间 提交于 2020-03-04 00:03:47
#include <bits/stdc++.h> using namespace std; const int maxn = 5e3 + 5; const int maxm = 5e5 + 5; namespace MST { struct edge { int u, v, w; }E[maxm]; int n, m; int tot = 0; void addedge(int u, int v, int w) { E[++tot].u = u; E[tot].v = v; E[tot].w = w; } int fa[maxn]; void init() { for (int i = 1; i <= n; i++) { fa[i] = i; } } int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } int Union(int u, int v) { int fu = find(u), fv = find(v); fa[fu] = fv; } int better(int i, int j) { if (j == 0)return 1; if (E[i].w != E[j].w) { return E[i].w < E[j].w; } else return i < j; } int best[maxn