最小生成树(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 ...
随机推荐
- [bzoj1056] [HAOI2008]排名系统
Description 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务 ...
- 【CF edu 30 C. Strange Game On Matrix】
time limit per test 1 second memory limit per test 256 megabytes input standard input output standa ...
- JavaScript词法作用域与调用对象
关于 Javascript 的函数作用域.调用对象和闭包之间的关系很微妙,关于它们的文章已经有很多,但不知道为什么很多新手都难以理解.我就尝试用比较通俗的语言来表达我自己的理解吧. 作用域 Scope ...
- 洛谷P1522 牛的旅行 Cow Tours
---恢复内容开始--- P1522 牛的旅行 Cow Tours189通过502提交题目提供者该用户不存在标签 图论 USACO难度 提高+/省选-提交该题 讨论 题解 记录 最新讨论 输出格式题目 ...
- TCP ------ keep-alive - 判断TCP链路的连接情况
TCP 是面向连接的 , 在实际应用中通常都需要检测对端是否还处于连接中.如果已断开连接,主要分为以下几种情况: 1. 连接的对端正常关闭,即使用 closesocket 关闭连接 ...
- 布局之BFC
BFC 什么是BFC,在哪里需要用到BFC,BFC有什么规则?生成BFC有什么条件?这几个问题,我将为大家一一解释,下面我们进入正题. BFC(Block formatting context)直译为 ...
- java简单发送邮件
需要的jar 据说是: <dependency> <groupId>javax.mail</groupId> <artifactId>mail</ ...
- sender的作用
https://www.evernote.com/shard/s227/sh/c2441a07-6b7e-4659-8452-9f768ee9cc66/73a115ed352421e10629 ...
- LeetCode 191:number of one bits
题目就是: Write a function that takes an unsigned integer and returns the number of ’1' bits it has (als ...
- Linux 下编译安装OpenCV【转】
转自:http://www.cnblogs.com/emouse/archive/2013/02/22/2922940.html OpenCV 2.2以后版本需要使用Cmake生成makefile文件 ...