最小生成树(Kruskal)(并查集)
最小生成树
时间限制: 1 Sec 内存限制: 64 MB
提交: 11 解决: 2
[提交][状态][讨论版]
题目描述
某个宇宙帝国有N个星球,由于宇宙的空间是三维的,因此每个星球的位置可以用三维坐标(X,Y,Z)来表示。任意两个不同的星球i和j都有一条边相连,边的距离是这样计算的:dis[i,j]=min(|Xi-Xj|,|Yi-Yj|,|Zi-Zj|),其中| | 符号表示取绝对值。现在让你来挑N-1条边,让这N个星球连通成一个最小生成树,输出构成最小生成树的N-1条边的长度总和。
输入
第1行,一个整数N(1≤N≤100000)。
接下来有N行,每行三个整数X,Y,Z,表示一个星球的坐标,-1000000000≤X,Y,Z≤1000000000。没有两个星球的位置完全重叠。
输出
1行,构成最小生成树的N-1条边的长度总和。
样例输入
5
11 -15 -15
14 -5 -15
-1 -1 -5
10 -4 -1
19 -4 19
样例输出
4
【分析】又一道最小生成树,还是Kruskal算法,本以为能很快写出来,但一开始的建边就把我难住了,注意N≤100000,如果用二重循环建边指定超时。
所以我们可以将x,y,z分别排序,然后用结构体放进优先队列,再Kruskal就行了。下面是AC代码。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#include<functional>
#define mod 1000000007
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int N=;
int n,m,k,cnt=-;
int d[][]= {,,,,,-,-,};
int parent[N+];
bool vis[N]; struct man {
int u,v,w;
bool operator<(const man&a)const{
return w>a.w;//最小值优先
}
} edg[N];//结构体存节点与节点之间的权值,x,y,z各存一份
priority_queue<man>q;//优先队列
struct mann
{
int x,y,z,id;
}mp[N];
bool cmp1(mann g,mann h) {return g.x<h.x;}
bool cmp2(mann g,mann h) {return g.y<h.y;}
bool cmp3(mann g,mann h) {return g.z<h.z;}//分别对x,y,z从小到大排序
void init() {
for(int i=; i<=n; i++)parent[i]=i;
}//初始化
int Find(int x) {
if(parent[x] != x) parent[x] = Find(parent[x]);
return parent[x];
}//查找并返回节点x所属集合的根节点
void Union(int x,int y) {
x = Find(x);
y = Find(y);
if(x == y) return;
parent[y] = x;
}//将两个不同集合的元素进行合并
void Build()//将空间图转化为树,分别将两点间的x,y,z方向上的距离存到优先队列,
{
sort(mp,mp+n,cmp1);
for(int i=;i<n;i++){
man s;
s.u=mp[i-].id;s.v=mp[i].id;s.w=abs(mp[i-].x-mp[i].x);
q.push(s);
}//从小到大排序,相邻两个数差距最小
sort(mp,mp+n,cmp2);
for(int i=;i<n;i++){
man s;
s.u=mp[i-].id;s.v=mp[i].id;s.w=abs(mp[i-].y-mp[i].y);
q.push(s);
}
sort(mp,mp+n,cmp3);
for(int i=;i<n;i++){
man s;
s.u=mp[i-].id;s.v=mp[i].id;s.w=abs(mp[i-].z-mp[i].z);
q.push(s);
}
}
void Kruskal() {
ll sumweight=;//生成树的总权值
int num=;//已经选用边的数目
int u,v;//顶点
init();
while() {
man t=q.top();q.pop();
u=t.u;
v=t.v;
if(Find(u)!=Find(v)) {
sumweight+=t.w;
num++;
Union(u,v);
}
if(num>=n-) break;//边已经全部建好
}
printf("%lld\n",sumweight);
}
int main() {
memset(vis,false,sizeof(vis));
int u,v,w;
cin>>n;
for(int i=; i<n; i++){
cin>>mp[i].x>>mp[i].y>>mp[i].z;mp[i].id=i;
}
Build();
Kruskal();
return ;
}
最小生成树(Kruskal)(并查集)的更多相关文章
- Minimum Spanning Tree.prim/kruskal(并查集)
开始了最小生成树,以简单应用为例hoj1323,1232(求连通分支数,直接并查集即可) prim(n*n) 一般用于稠密图,而Kruskal(m*log(m))用于系稀疏图 #include< ...
- TOJ 2815 Connect them (kruskal+并查集)
描述 You have n computers numbered from 1 to n and you want to connect them to make a small local area ...
- Connect the Campus (Uva 10397 Prim || Kruskal + 并查集)
题意:给出n个点的坐标,要把n个点连通,使得总距离最小,可是有m对点已经连接,输入m,和m组a和b,表示a和b两点已经连接. 思路:两种做法.(1)用prim算法时,输入a,b.令mp[a][b]=0 ...
- POJ 3723 Conscription (Kruskal并查集求最小生成树)
Conscription Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14661 Accepted: 5102 Des ...
- [CF891C] Envy - Kruskal,并查集
给出一个 n 个点 m条边的无向图,每条边有边权,共 Q次询问,每次给出 \(k\)条边,问这些边能否同时在一棵最小生成树上. Solution 所有最小生成树中某权值的边的数量是一定的 加完小于某权 ...
- hdu5441(2015长春赛区网络赛1005)类最小生成树、并查集
题意:有一张无向图,一些点之间有有权边,某条路径的值等于路径上所有边的边权的最大值,而某个点对的值为这两点间所有路径的值的最小值,给出多个询问,每个询问有一个值,询问有多少点对满足其值小于等于询问值. ...
- 搭桥|codevs1002|最小生成树|Prim|并查集|Elena
1002 搭桥 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点 ...
- 习题:过路费(kruskal+并查集+LCA)
过路费 [问题描述]在某个遥远的国家里,有 n 个城市.编号为 1,2,3,…,n.这个国家的政府修 建了 m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市 T 需 要收取的过路费 ...
- hdu 1863 畅通工程(Kruskal+并查集)
畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- 线段树、最短路径、最小生成树、并查集、二分图匹配、最近公共祖先--C++模板
线段树(区间修改,区间和): #include <cstdio> #include <iostream> #include <cstring> using name ...
随机推荐
- picks loves segment tree I
picks loves segment tree I 题目背景 来源: \(\text {2018 WC Segment Tree Beats}\) 原作者: \(\text {C_SUNSHINE} ...
- 【COGS 14】 [网络流24题] 搭配飞行员 网络流板子题
用网络流水二分图的模型(存一下板子) #include <cstdio> #include <cstring> #include <algorithm> #defi ...
- 收藏一个漂亮的Flash焦点图切换
网上闲逛的时候发现一个Flash焦点图效果,跟喜欢,然后就下载回来,收集在这里,以便以后方便取用.这个Flash使用方法也是相当简单的,如果你喜欢,也可以从这里查看源代码下载. Flash 焦点图效果 ...
- JavaScript词法作用域与调用对象
关于 Javascript 的函数作用域.调用对象和闭包之间的关系很微妙,关于它们的文章已经有很多,但不知道为什么很多新手都难以理解.我就尝试用比较通俗的语言来表达我自己的理解吧. 作用域 Scope ...
- boost 文件操作
void testFileSystem() { boost::filesystem::path path("/test/test1"); //初始化 boost::filesyst ...
- POJ2594:Treasure Exploration(Floyd + 最小路径覆盖)
Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 9794 Accepted: 3 ...
- java的多构造函数的处理方式
/** * */ package P; import java.awt.List; import java.lang.reflect.Array; import java.util.ArrayList ...
- 如何用listview显示服务端数据
https://www.cnblogs.com/caobotao/p/5061627.html
- 480000 millis timeout while waiting for channel to be ready for write异常处理
2014-08-25 15:35:05,691 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: DatanodeRegistration( ...
- Idea IntelliJ远程调试教程
总结 第一步:修改startup.sh 在倒第二行加上export JPDA_ADDRESS=8787 最后一行在start前面加上" jpda " 第二步:配置Idea, ...