最小生成树

时间限制: 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)(并查集)的更多相关文章

  1. Minimum Spanning Tree.prim/kruskal(并查集)

    开始了最小生成树,以简单应用为例hoj1323,1232(求连通分支数,直接并查集即可) prim(n*n) 一般用于稠密图,而Kruskal(m*log(m))用于系稀疏图 #include< ...

  2. 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 ...

  3. Connect the Campus (Uva 10397 Prim || Kruskal + 并查集)

    题意:给出n个点的坐标,要把n个点连通,使得总距离最小,可是有m对点已经连接,输入m,和m组a和b,表示a和b两点已经连接. 思路:两种做法.(1)用prim算法时,输入a,b.令mp[a][b]=0 ...

  4. POJ 3723 Conscription (Kruskal并查集求最小生成树)

    Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14661   Accepted: 5102 Des ...

  5. [CF891C] Envy - Kruskal,并查集

    给出一个 n 个点 m条边的无向图,每条边有边权,共 Q次询问,每次给出 \(k\)条边,问这些边能否同时在一棵最小生成树上. Solution 所有最小生成树中某权值的边的数量是一定的 加完小于某权 ...

  6. hdu5441(2015长春赛区网络赛1005)类最小生成树、并查集

    题意:有一张无向图,一些点之间有有权边,某条路径的值等于路径上所有边的边权的最大值,而某个点对的值为这两点间所有路径的值的最小值,给出多个询问,每个询问有一个值,询问有多少点对满足其值小于等于询问值. ...

  7. 搭桥|codevs1002|最小生成树|Prim|并查集|Elena

    1002 搭桥  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点 ...

  8. 习题:过路费(kruskal+并查集+LCA)

    过路费  [问题描述]在某个遥远的国家里,有 n 个城市.编号为 1,2,3,…,n.这个国家的政府修 建了 m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市 T 需 要收取的过路费 ...

  9. hdu 1863 畅通工程(Kruskal+并查集)

    畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  10. 线段树、最短路径、最小生成树、并查集、二分图匹配、最近公共祖先--C++模板

    线段树(区间修改,区间和): #include <cstdio> #include <iostream> #include <cstring> using name ...

随机推荐

  1. [Leetcode] Populating next right pointer in each node ii 填充每个节点的右指针

    Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...

  2. JSP AJAX之Form序列化登录体验

    package web; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletExc ...

  3. Codeforces Round #523 (Div. 2) A. Coins

    A. Coins 题目链接:https://codeforc.es/contest/1061/problem/A 题意: 给出n和s,要在1-n中选数(可重复),问最少选多少数可以使其和为s. 题解: ...

  4. BZOJ1040 骑士 基环外向树

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6421  Solved: 2544[Submit][Status ...

  5. wget下载HTTPS链接

    wget -c -O master.zip --no-check-certificate https://github.com/mitsuhiko/flask/archive/master.zip # ...

  6. nginx,docker反向代理

    1. [root@javanginx ~]# cat /etc/nginx/nginx.conf user root root;worker_processes 4;error_log /var/lo ...

  7. [05]Git查看、删除、重命名远程分支和tag

    Git查看.删除.重命名远程分支和tag 2015-06-15:加入姊妹篇: 2013-11-06:加入重命名远程分支的内容: 2013-01-09:加入删除远程tag的内容. 姊妹篇:使用Git.G ...

  8. java使用JNA调用dll

    1.自己搞一个dll出来.参考下面链接 http://blog.csdn.net/lqena/article/details/46357165. 2.下载jar jna-4.2.1.jar. 3.复制 ...

  9. 【hdu3080】01背包(容量10^7)

    [题意]n个物品,有wi和vi,组成若干个联通块,只能选取一个联通块,问得到m的价值时最小要多少空间(v).n<=50,v<=10^7 [题解] 先用并查集找出各个联通块. 这题主要就是v ...

  10. 转: Java安全停止线程方法

    转: http://blog.csdn.net/flyingpig4/article/details/7675557 1.早期Java提供java.lang.Thread类型包含了一些列的方法star ...