蓝桥杯20534爆破 java

这道题本质是最小生成树(MST)问题

这道题的模型是:

  1. 每个魔法阵是一个 "节点"。
  2. 两个魔法阵之间的 "边权" 是:若相交(距离≤半径和)则边权为 0;否则边权为「圆心距 - 半径和」。
  3. 我们需要求最小生成树的总权值(让所有节点连通的最小边权和)。

我们可以用Prim 算法,该算法的核心是从一个起点开始,逐步将距离当前连通集合最近的节点加入集合,最终形成最小生成树。

复制代码
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

import java.util.Arrays;
public class Main {
    public static void main(String[] args) {
           Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        //创建数组存放圆的数据
        int[][] circle = new int[n][3];
        for (int i = 0; i < circle.length; i++) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            int r = sc.nextInt();
            circle[i][0] = x;
            circle[i][1] = y;
            circle[i][2] = r;
        }
        sc.close();
        // 构建邻接矩阵:graph[i][j]表示顶点i到j的边权
        double[][] graph = new double[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == j) {     //表示为同一个魔法阵
                    graph[i][j] = 0;
                } else {
                    int x1 = circle[i][0], y1 = circle[i][1], r1 = circle[i][2];
                    int x2 = circle[j][0], y2 = circle[j][1], r2 = circle[j][2];
                    double dist = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
                    // 边权:相交则为0,否则为"距离 - 两半径之和"
                    graph[i][j] = Math.max(0, dist - r1 - r2);
                }
            }
        }
        // Prim算法初始化
        double[] dist = new double[n]; // 记录每个顶点到当前生成树的最小距离
        Arrays.fill(dist, Double.MAX_VALUE);
        boolean[] visited = new boolean[n];// 标记顶点是否已加入生成树
        dist[0] = 0;// // 从顶点0开始构建生成树
        visited[0] = true; // 标记顶点0已加入生成树
        // 初始化距离数组为从顶点0出发的边权
        for (int v = 0; v < n; v++) {
            dist[v] = graph[0][v];
        }
        double totalLength = 0;// 记录最小生成树的总权重
        for (int i = 1; i < n ; i++) { // 生成树需要n-1条边
            // 找到"未访问且距离当前生成树最近"的顶点u
            int u = -1;
            double minDist = Double.MAX_VALUE;
            for (int j = 0; j < n; j++) {
                if (!visited[j] && dist[j] < minDist) {
                    minDist = dist[j];
                    u = j;
                }
            }

            visited[u] = true; // 将u加入生成树
            totalLength += minDist; // 累加边权

            // 更新其他未访问顶点到生成树的最小距离
            for (int v = 0; v < n; v++) {
                if (!visited[v] && graph[u][v] < dist[v]) {
                    dist[v] = graph[u][v];
                }
            }
        }
        System.out.println( String.format("%.2f", totalLength));
    }
}
相关推荐
benbenAItalk4 小时前
数字人口播视频的批量生产实践:素材规范、任务编排与质量验收
java·前端·音视频
sunshine22 girl4 小时前
Java学习二 基本语法2, 算术运算符
java·学习
2601_962218615 小时前
万象生鲜系统业财一体化底层打通技术自动生成经营账单
大数据·数据库·人工智能·python·算法
niucloud-admin5 小时前
JAVA V6 多商户商城 开发文档——插件目录结构
java·开发语言
2601_962885725 小时前
如何用 Python 扫描 A 股跳空缺口并统计缺口回补概率?
java·前端·python
吞下星星的少年·-·5 小时前
The 2026 ICPC Asia East Continent Online Contest (II)(构造)
数据结构·算法
滕州市燕猫虎计算机科技工作室个体工商户5 小时前
Java锁
java·开发语言
stolentime6 小时前
洛谷P10515 转圈题解
c++·算法·数学建模·贪心算法
shehuiyuelaiyuehao7 小时前
1计算机是如何工作的
java·计算机网络
和裕7 小时前
蜂窝板 vs 七层瓦楞重型纸箱:大件工业设备运输性能与成本全对比
大数据·运维·网络·人工智能·算法