Description

分析:
普通模拟?TLE大法,预计20分.
仔细分析......
两个点连在一起的时间是它们之间曼哈顿距离的一半向上取整......
要所有点联通,联想到航空管制(最小生成树的入门题)和最小生成树
这样就简单了,每两个点之间连一条边,权值是两个点联通的距离.
顺手敲了个最小生成树想骗点分竟然A了,还是第二优解......
和普通的最小生成树的求总大小不同,这里是求其中的最大边.
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#define SIZE 2010
using namespace std;
struct edge // 一条边
{
int u, v, w;
};
vector<edge> graph;
int x[SIZE], y[SIZE], fa[SIZE];
bool comp(edge a, edge b) // 按权值排序
{
return a.w < b.w;
}
int find(int x) // 并查集:找祖先
{
return (fa[x]) ? fa[x] = find(fa[x]) : x;
}
int main(void)
{
int n, i, cnt = 1, j, fx, fy;
scanf("%d", &n);
for (i = 1; i <= n; ++i)
{
scanf("%d%d", &x[i], &y[i]);
for (j = 1; j < i; ++j)
{
graph.push_back({i, j, abs(x[i] - x[j]) + abs(y[i] - y[j]) + 1 >> 1}); // 将两个点联通的时间作为权值
}
}
sort(graph.begin(), graph.end(), comp);
for (i = 0; i < graph.size(); ++i) // 跑一遍普通的K算法生成树
{
fx = find(graph[i].u);
fy = find(graph[i].v);
if (fx != fy) // 两点不连通,加边
{
if (++cnt == n)
{
printf("%d", graph[i].w); // 输出最大边权,完工
return 0;
}
fa[fx] = fy; // 合并
}
}
return 0;
}

本文介绍了一种利用最小生成树算法解决特定问题的方法。通过分析点之间的曼哈顿距离来确定连接时间,并运用Kruskal算法求解最小生成树中的最大边权值,适用于竞赛编程中的快速解题。
3249

被折叠的 条评论
为什么被折叠?



