精华内容
下载资源
问答
  • 2020-07-09 18:45:05

    有会用kruskal算法求最小生成树的吗?代价来

    更多相关内容
  • 之前都是看书,大部分也是c++的实现,但是搞前端不能忘了JS啊,所以JS实现一遍这两个经典的最小生成树算法。 一、权重图和最小生成树 权重图:图的边带权重 最小生成树:在连通图的所有生成树中,所有边的权重和...
  • 求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。 由 V 中的全部 n 个顶点和 E 中 n−1 条边...

    给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。

    求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。

    给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。

    由 V 中的全部 n 个顶点和 E 中 n−1 条边构成的无向连通子图被称为 G 的一棵生成树,其中边的权值之和最小的生成树被称为无向图 G 的最小生成树。

    输入格式
    第一行包含两个整数 n 和 m。

    接下来 m 行,每行包含三个整数 u,v,w,表示点 u 和点 v 之间存在一条权值为 w 的边。

    输出格式
    共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。

    数据范围
    1≤n≤105,
    1≤m≤2∗105,
    图中涉及边的边权的绝对值均不超过 1000。

    输入样例:
    4 5
    1 2 1
    1 3 2
    1 4 3
    2 3 2
    3 4 4
    输出样例:
    6
    题解:Kruskal算法主要思想就是先给所有权边从小到大排序,然后再判断点是否在连通块内,若不在则累加权值并将点放入连通块,连通块用并查集来存储。
    代码:

    #include<iostream>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    int n,m,res,cnt;
    const int N=200010;
    int s[N];
    struct px{
    	int a,b,w;
    }p[N];
    bool cmp(px a,px b){
    	return a.w<b.w;
    }
    int find(int a){
    	if(s[a]!=a)s[a]=find(s[a]);
    	return s[a];
    }
    int k(){
    	for(int i=1;i<=m;i++)
    	{
    		int a=p[i].a,b=p[i].b,w=p[i].w;
    		a=find(a);b=find(b);
    		if(a!=b)
    		{
    			s[a]=b;
    			res+=w;
    			cnt++;
    		}
    	}
    	if(cnt==n-1)return res;
    	else return -1;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)
    	{
    		int a,b,w;
    		scanf("%d%d%d",&a,&b,&w);
    		p[i]={a,b,w};
    	}
    	sort(p+1,p+1+m,cmp);
    	for(int i=1;i<=n;i++)s[i]=i;
    	int t=k();
    	if(t==-1)printf("impossible\n");
    	else printf("%d\n",res);
    }
    
    展开全文
  • kruskal算法求最小生成树 java代码
  • Kruskal 算法是一种常见并且好写的最小生成树算法,由 Kruskal 发明。该算法的基本思想是从小到大加入边。算法实现基于贪心算法。 对于一个拥有 nnn 个顶点 mmm 条边的图,其最小生成树包括 n−1n-1n−1 条边。 这个...

    概述

    Kruskal 算法是一种常见并且好写的最小生成树算法,由 Kruskal 发明。该算法的基本思想是从小到大加入边。算法实现基于贪心算法。
    对于一个拥有 n n n 个顶点 m m m 条边的图,其最小生成树包括 n −

    展开全文
  • Prim算法与Kruskal算法 求最小生成树 源代码 实验报告 完整
  • 求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。 由 V 中的全部 n 个顶点和 E 中 n−1 条边...

    题目链接点击查看

    题目描述

    给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。

    求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。

    给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。

    由 V 中的全部 n 个顶点和 E 中 n−1 条边构成的无向连通子图被称为 G 的一棵生成树,其中边的权值之和最小的生成树被称为无向图 G 的最小生成树。

    输入输出格式

    输入

    第一行包含两个整数 n 和 m。
    接下来 m 行,每行包含三个整数 u,v,w,表示点 u 和点 v 之间存在一条权值为 w 的边。

    输出

    共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。

    输入输出样例

    输入

    4 5
    1 2 1
    1 3 2
    1 4 3
    2 3 2
    3 4 4

    输出

    6

    题目分析

    Kruskal算法常用于解决稀疏图的最小生成树问题。Kruskal算法也是基于贪心算法思想,不过与Prim算法不同,前者以边为主体,后者以点为主体。算法一般分为三步走 : 1. 先将图中边按权重由小到大排序。 2. 每次择取没选过的权重最小的边,判断此边加入最小生成树边集后是否构成回路,如构成回路则舍弃。 3. 选取n - 1条边使n个点相连。

    以上是Kruskal算法的核心步骤。而且,我们使用结构体来存储图中边,要想将图中边按权重从小到大排序,需要在结构体内部重载 < 符号。 判断是否构成回路,我们这里要用到并查集,在Kruskal函数中,先初始化并查集,即每个点的所属集合的根节点为其本身,由于边已经排完序,我们从小到大依次选择,如果边的两个端点不再同一个集合中,则我们将两个点所属集合合并,表明将这条边加入集合。由此可见,并查集维护的是最小生成树的边集,如果两个点不属于同一个集合,说明将两个顶点之间的边加入并查集不会生成回路。我们在找每一个集合的根节点的时候,用到的是路径压缩算法。在此过程中我们用res记录最小生成树每一条边的权重,用cnt记录边的条数,每一次在判断不构成回路时,将cnt ++ ,res += w。在最后如果cnt < n -1 即选取的边数小于n - 1意味着构不成最小生成树,我们返回INF,反之则返回我们计算的权重和res。详见如下代码。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 1e5 + 7, INF = 0x3f3f3f3f, M = 2e5 + 7;
    int n, m;
    int p[N];
    struct Edge {
    	int v1, v2, w;
    	bool operator < (const Edge &W) const {//重载 < 号 结构体比较按照的是边权重的大小 
    	  return w < W.w;
    	}
    }edges[M];
    int find(int x) {
    	if (p[x] != x) p[x] = find(p[x]);//路径压缩 
    	return p[x]; 
    }
    int kruskal() {
    	sort(edges, edges + m);//将所有边按照权重大小进行排序。 
    	for (int i = 1; i <= n; i ++ ) p[i] = i;//初始化并查集 
    	int res  = 0, cnt = 0;
    	for (int i = 0; i < m; i ++ ) {
    		int v1 = edges[i].v1, v2 = edges[i].v2, w = edges[i].w;
    		v1 = find(v1), v2 = find(v2);
    		if (v1 != v2) {
    			p[v1] = v2;
    			res += w;
    			cnt ++ ;
    		} 
    	} 
    	if (cnt < n - 1) return INF;
    	return res;
    }
    int main() {
    	cin >> n >> m;
    	for (int i = 0; i < m; i ++ ) {
    		int v1, v2, w;
    		cin >> v1 >> v2 >> w;
    		edges[i] = {v1, v2, w}; 
    	}
    	int t = kruskal();
    	if (t == INF) cout << "impossible" << endl;
    	else cout << t << endl; 
    	return 0;
    } 
    

    在此给出Kruskal算法的相关模板

    时间复杂度是 O(mlogm), n 表示点数,m 表示边数
    int n, m;       // n是点数,m是边数
    int p[N];       // 并查集的父节点数组
    
    struct Edge     // 存储边
    {
        int a, b, w;
    
        bool operator< (const Edge &W)const
        {
            return w < W.w;
        }
    }edges[M];
    
    int find(int x)     // 并查集核心操作
    {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    
    int kruskal()
    {
        sort(edges, edges + m);
    
        for (int i = 1; i <= n; i ++ ) p[i] = i;    // 初始化并查集
    
        int res = 0, cnt = 0;
        for (int i = 0; i < m; i ++ )
        {
            int a = edges[i].a, b = edges[i].b, w = edges[i].w;
    
            a = find(a), b = find(b);
            if (a != b)     // 如果两个连通块不连通,则将这两个连通块合并
            {
                p[a] = b;
                res += w;
                cnt ++ ;
            }
        }
    
        if (cnt < n - 1) return INF;
        return res;
    }
    
    
    展开全文
  • 所以Kruskal算法的第一步是给所有的边按照从小到大的顺序排序。这一步可以直接使用库函数qsort或者sort。接下来从小到大依次考察每一条边(u,v)。 具体实现过程如下: <1> 设一个有n个顶点的连通网络为G(V,E)...
  • Kruskal算法求最小生成树 给定一个n个点m条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。 给定一张边带权的无向图G=(V, E),其中V...
  • NULL 博文链接:https://128kj.iteye.com/blog/1705936
  • Kruskal算法求最小生成树一、算法学习前先要知道1.最小生成树概念2.数据结构:并查集二、Kruskal算法实现步骤1.把所有的边排序2.遍历所有的边三、Kruskal算法的代码实现 一、算法学习前先要知道 1.最小生成树概念 ...
  • 克鲁斯卡尔算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。 把图中的所有边按代价从小到大排序; 把图中的n个顶点看成独立的n棵树组成的...
  • Kruskal算法求最小生成树Edge结构体,Graph结构体Kruskal算法求最小生成树完整源码(定义,实现,main函数测试) Edge结构体,Graph结构体 // a structure to represent a weighted edge in graph struct Edge { ...
  • C++ Kruskal算法求最小生成树

    千次阅读 2020-08-01 23:57:52
    最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法出。 ————百度百科 Kruskal算法简述 假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:
  • 求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。 给定一张边带权的无向图G=(V,E),其中V表示图中点的集合,E表示图中边的集合,n=|V|,m=|E|。 由V中的全部n个顶点和E中n−1条边构成的无向连通...
  • 有n个结点,则所最小生成树需含有n-1条边;将图中的边,划分为两个集合,一个集合是加入了生成树的边集合(为方便称为集合A),一个是未加入生成树的边集合(为方便称为集合B)。根据贪心算法原则,每次从集合B...
  • Prim算法求最小生成树 给定一个n个点m条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。 给定一张边带权的无向图G=(V, E),其中V表示...
  • 数据结构-kruskal算法求最小生成树_实验报告.doc
  • 求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。 给定一张边带权的无向图G=(V, E),其中V表示图中点的集合,E表示图中边的集合,n=|V|,m=|E|。 由V中的全部n个顶点和E中n-1条边构成的无向...
  • 最小生成树(Prim,Kruskal)C++代码实现 (可运行,含测试用例,有输出,注释详细) 对于一个带权连通图,生成树不同,树中各边上权值总和也不同,权值总和最小的生成树则称为图的最小生成树
  • kruskal算法最小生成树算法,内有示例,也可改成函数(在示例状态下被注释,要改成函数,取消那个注释,改下函数名或者文件名就行)
  • 从文件中Test类用来读取数据文件,可事先将数据输入文件中,Kruskal算法解决最小生成树
  • Kruskal算法求最小生成树 给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G=(V,E),...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,149
精华内容 9,659
关键字:

kruskal算法求最小生成树