IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 八中生成树1 [MST](C++) -> 正文阅读

[C++知识库]八中生成树1 [MST](C++)

作者:recommend-item-box-tow

前言:

? ? ? ? 好久没有更新了,最近学习压力有点大,而且队里学的东西越来越变态,所以近期我会试着更新一些难题,至于水题嘛。。。我们训练时就没有水题。。。

题目:

八中草坪上有N个水龙头,位于(x_i,y_i
求将N个水龙头连通的最小费用。
任意两个水龙头可以修剪水管,费用为欧几里得距离的平方。
校长只愿意修费用大于等于C的水管。

输入

第一行给出NC
接下来N行给出点的坐标x,y
1<=N??????? <=200
1<=x_i, y_i<=1000
1<=C<=1000000

输出

输出最小费用,如果无解输出-1

样例输入:

3 11
0 2
5 0
4 3

?样例输出:

46 

?思路:

1:这道题用最小生成树解决,

我用的是Kruskal算法:

其思路在于将每条边按边权从小到大排序,

每次取相对小的边,

并查集判断连接该边会不会形成图

如果会,则跳过该边

如不会,则进行操作

2:要用到欧几里得距离的知识;

二维空间公式:S=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2010;
int n;
int c;
int fa[N];
int cnt=0;
int ans=0;
int x[N],y[N];

struct edge {
	int x,y;
	int val;
}e[N*N];

int Euclidean_Metric(int x_x,int x_y,int y_x,int y_y) {//欧几里得距离 
	return (x_x-y_x)*(x_x-y_x)+(x_y-y_y)*(x_y-y_y);//由题意,无需开根 
}

void put (int a,int b) {//建树 
	cnt++;
	e[cnt].x=a;
	e[cnt].y=b;
	e[cnt].val=Euclidean_Metric(x[a],y[a],x[b],y[b]);
}

int find(int x) {
	if(fa[x]!=x)
	    fa[x]=find(fa[x]);
	return fa[x];
}

void unite(int x,int y) {//将x,y放入同一个集合中 
	int p=fa[x],q=fa[y];
	if(p!=q)
	    fa[q]=p;
}

bool cmp(edge a,edge b) {//按边权排序 
	return a.val<b.val;
}



void MST_Kruskal() {//求最小生成树 
	int tot=0;//最小生成树边数 

	for(int i=1;i<=cnt;i++) {
		if(find(e[i].x)==find(e[i].y)||e[i].val<c) 
		    continue;//如果会形成图 或 边权小于C ,则跳过	
		//否则进行以下操作: 
		unite(e[i].x,e[i].y); //将该边连接的两点放到同一个集合里,表示两点联通 
		tot++;//边数++ 
		ans+=e[i].val;//加上边权 
	}
	if(tot<n-1)//因为N个点的最小生成树有N-1条边 
	    puts("-1");//tot小于N,则构不成最小生成树 
	else//若能构成,输出代价 
	    printf("%d",ans);
}

int main() {
	scanf("%d%d",&n,&c);
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=n;i++) 
		scanf("%d%d",&x[i],&y[i]);
	for(int i=1;i<=n;i++) {
		for(int j=i+1;j<=n;j++) {
			put(i,j);
		}
	}
	sort(e+1,e+cnt+1,cmp);
	MST_Kruskal();
	return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 17:26:01  更:2022-05-18 17:27:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:39:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码