3366 【模板】最小生成树(Kruskal)

题目描述

如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz

输入输出格式

输入格式:

第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)

接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi

输出格式:

输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz

代码:

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 struct edge{
 6     int s, e, w;
 7     edge(int ss, int ee, int ww):s(ss), e(ee), w(ww){}
 8     bool operator<(const edge&e1){
 9         return w<e1.w;
10     }
11 };
12 vector<edge>edges;
13 vector<int>par;
14 int getpar(int x){
15     if(par[x]!=x){
16         par[x] = getpar(par[x]);
17     }
18     return par[x];
19 }
20 void merge(int x, int y){
21     if(getpar(x)==getpar(y)) return;
22     par[getpar(x)] = getpar(y);
23 }
24 int main(){
25     int n, m;
26     int i;
27     cin>>n>>m;
28     par.resize(n+1);
29     for(i = 1; i <= n; i++)
30         par[i] = i;
31     for(i = 1; i <= m; i++){
32         int s, e, w;
33         cin>>s>>e>>w;
34         edges.push_back(edge(s,e,w));
35     }
36     sort(edges.begin(),edges.end());
37     int done = 0, way = 0;
38     for(i = 0; i <edges.size(); i++){
39         if(getpar(edges[i].s)!=getpar(edges[i].e)){
40             merge(edges[i].s, edges[i].e);
41             done++;
42             way += edges[i].w;
43         }
44         if(done == n-1) break;
45     }
46     cout<<way<<endl;
47     return 0;
48 }

备注:

Frankly speaking,我觉得Kruskal比Prim要好理解+好写。只是把边排序,再加一个并查集就可以实现。在某种程度上更好理解。

再去看看图论的内容。

时间: 2024-12-27 09:31:01

3366 【模板】最小生成树(Kruskal)的相关文章

模板——最小生成树kruskal算法+并查集数据结构

并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每个点只保存祖先,不保存父亲) 最小生成树kruskal:贪心算法+并查集数据结构,根据边的多少决定时间复杂度,适合于稀疏图 核心思想贪心,找到最小权值的边,判断此边连接的两个顶点是否已连接,若没连接则连接,总权值+=此边权值,已连接就舍弃继续向下寻找: 并查集数据结构程序: #include<ios

SOJ4339 Driving Range 最小生成树 kruskal算法

典型的最小生成树 然后求最大的一条边 附上链接 http://cstest.scu.edu.cn/soj/problem.action?id=4339 需要注意的是有可能有 "IMPOSSIBLE" 的情况 这里用一个flag标记 记录所并的节点 只有flag = n时才能成功 负责就 "IMPOSSIBLE" 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring&g

ZOJ 3204 Connect them (C) 最小生成树kruskal

Connect them Time Limit: 1 Second      Memory Limit: 32768 KB You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN). All connections are two-way (that is connecting computers i and j is the sa

HDU2988 Dark roads 【最小生成树Kruskal】

Dark roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 583    Accepted Submission(s): 253 Problem Description Economic times these days are tough, even in Byteland. To reduce the operating

最小生成树 kruskal算法简介

生成树--在一个图中的一个联通子图  使得所有的节点都被(访问) 最小生成树 (MST) 即联通子图的总代价(路程)最小 已知的一个图 有n个点 m条边 kruskal的算法如下 先对边从小到大排序 从最小的边起,不停的合并这条边的两个节点到一个集合,如果这条边的两个节点已经在一个集合里,则无视,否则形成回路(显然错误)直到所有的节点并到一个集合里 这里需要用到并查集来合并节点 1 int cmp(const int i,const int j) { 2 return w[i] < w[j];

最小生成树 Kruskal算法

Kruskal算法 1.概览 Kruskal算法是一种用来寻找最小生成树的算法,由Joseph Kruskal在1956年发表.用来解决同样问题的还有Prim算法和Boruvka算法等.三种算法都是贪婪算法的应用.和Boruvka算法不同的地方是,Kruskal算法在图中存在相同权值的边时也有效. 2.算法简单描述 1).记Graph中有v个顶点,e个边 2).新建图Graphnew,Graphnew中拥有原图中相同的e个顶点,但没有边 3).将原图Graph中所有e个边按权值从小到大排序 4)

SDUT 2933-人活着系列之Streetlights(最小生成树Kruskal+并查集实现)

人活着系列之Streetlights Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 人活着如果是为了家庭,亲情----可以说是在这个世界上最温暖人心的,也是最让人放不下的,也是我在思索这个问题最说服自己接受的答案.对,也许活着是一种责任,为了繁殖下一代,为了孝敬父母,男人要养家糊口,女人要生儿育女,就这样循环的过下去,但最终呢?还是劳苦愁烦,转眼成空呀! 为了响应政府节约能源的政策,某市要对路灯进行改革,已知该市有n个城镇,

无向图最小生成树Kruskal算法

问题 最小生成树的Kruskal算法 描述:有A.B.C.D四个点,每两个点之间的距离(无方向)是(第一个数字是两点之间距离,后面两个字母代表两个点):(1,'A','B'),(5,'A','C'),(3,'A','D'),(4,'B','C'),(2,'B','D'),(1,'C','D') 生成边长和最小的树,也就是找出一种连接方法,将各点连接起来,并且各点之间的距离和最小. 思路说明: Kruskal算法是经典的无向图最小生成树解决方法.此处列举两种python的实现方法.这两种方法均参考

最小生成树Kruskal算法的提出者Joseph Bernard Kruskal,Jr.

熟悉算法中的最小生成树的朋友都晓得有一个Kruskal算法,这个算法就是由题目中那个名字很长的人提出的.因为他功绩卓越,尊称他为Kruskal. Kruskal生于1928年1月29日,卒于2010年9月19日,美国人,维基里的词条中包含的头衔是:数学家.统计学家.计算机科学家.心理测量学专家. kruskal分别就读过芝加哥大学和普林斯顿大学,1954年获得博士学位. 下面链接中是一篇几年他的文章,从中可以了解他的更多成就.顺便说一句,他的父母和兄弟也都很牛. http://pan.baidu

【模版】最小生成树Kruskal模版

最小生成树简单来说就是在一个有$n$条边的有权无向连通图中选出$n-1$条边,使图连通并且这$n-1$条边的边权和最小. Kruskal算法是用一种贪心的思想,先将所有的边按边权排序,按边权从小到大顺序枚举边,如果起点和终点不在一个集合,就选这条边,并将起点和终点合并成一个集合:反之则不选此边.集合可以用并查集维护. (以上内容纯属瞎编,若要系统学习请百度) 下面是模版 //最小生成树(Kruskal)模版 //By LC 2017.2.19整理 #include <cstdio> #incl