[JSOI2010]GROUP 部落划分 GROUP 把n个点分成k个集, 集合间最小距离最大 最小生成树变形
题目
GROUP 部落划分 GROUP(https://ac.nowcoder.com/acm/problem/20181)
题目描述
聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗。只是,这一切都成为谜团了——聪聪根本就不知道部落究竟是如何分布的。 不过好消息是,聪聪得到了一份荒岛的地图。地图上标注了N个野人居住的地点(可以看作是平面上的坐标)。
我们知道,同一个部落的野人总是生活在附近。我们把两个部落的距离,定义为部落中距离最近的那两个居住点的距离。聪聪还获得了一个有意义的信息——这些野人总共被分为了K个部落!这真是个好消息。聪聪希望从这些信息里挖掘出所有部落的详细信息。
他正在尝试这样一种算法: 对于任意一种部落划分的方法,都能够求出两个部落之间的距离,聪聪希望求出一种部落划分的方法,使靠得最近的两个部落尽可能远离。
例如,下面的左图表示了一个好的划分,而右图则不是。请你编程帮助聪聪解决这个难题。
输入描述:
第一行包含两个整数N和K(1 ≤ N ≤ 1000,1 < K ≤ N),分别代表了野人居住点的数量和部落的数量。
接下来N行,每行包含两个正整数x,y,描述了一个居住点的坐标(0 ≤ x, y ≤ 10000)
输出描述:
输出一行,为最优划分时,最近的两个部落的距离,精确到小数点后两位。
输入
4 2
0 0
0 1
1 1
1 0
输出
1.00
思路
题目意思是把n个点划分成k个集合。使得集合之间的最小距离最大。
点两两之间都有边。
我们考虑最后一定有k个连通块。并且希望优先用短边来连接得到这k个连通块。
那么考虑最小生成树的过程。每次连接一条边,就会减少1个连通块,那么现在我们只要
连接n-k条边。就得到了一个k连通块的图。而且优先选择的短边。那么第n-k+1条可连接的边就是答案。
#include <bits/stdc++.h>
#define LL long long
#define F first
#define S second
#define debug(x) cerr << "Line(" << __LINE__ << ") -> " << #x << " is " << x << endl
using namespace std;
struct Edge {
int f, to;
double w;
int nxt;
} E[2000005];
int head[2000005], cut=0;
void Addedge(int x, int y, double w) {
E[++cut]= {x, y, w, head[x]};
head[x]=cut;
}
int x[1005], y[1005];
double dis(int i,int j) {
return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
int f[1005];
int fd(int x) {
if(!f[x])
return x;
return f[x]=fd(f[x]);
}
int main() {
int n, k;
scanf("%d%d", &n, &k);
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++) {
Addedge(i, j, dis(i, j));
}
}
sort(E+1, E+cut+1, [](Edge &a, Edge &b) {
return a.w<b.w;
});
int tot=0;
for(int i=1; i<=cut; i++) {
int x=fd(E[i].f), y=fd(E[i].to);
if(x!=y) {
tot++;
f[x]=y;
}
if(tot==n-k+1) {
printf("%.2f\n", E[i].w);
break;
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)