当前位置: 首页 > news >正文

《CF1245D Shichikuji and Power Grid》

题目描述

Shichikuji 是南黑蜗牛寺的新任驻守神明。她的第一项工作如下:

在 X 县有 n 个新城市。城市编号从 1 到 n。第 i 个城市位于距离神社北方 xi​ 千米、东面 yi​ 千米的位置。可能存在 i=j 但 (xi​,yi​)=(xj​,yj​) 的情况。

Shichikuji 必须为每个城市供电,可以通过在该城市建造发电站,或者将该城市与已经有电的城市连接来实现。也就是说,如果一个城市自身有发电站,或者通过直接连接或一系列连接与有电的城市相连,则该城市就有电。

  • 在第 i 个城市建造发电站的费用为 ci​ 日元;
  • 将第 i 个城市与第 j 个城市连接的费用为每千米 (ki​+kj​) 日元。电线只能沿着正北、正南、正东、正西方向铺设,电线可以相互交叉。每根电线的两个端点都必须在某个城市。如果第 i 个城市与第 j 个城市连接,则电线会沿任意一条最短路径铺设。因此,连接第 i 个城市与第 j 个城市所需电线的长度为 ∣xi​−xj​∣+∣yi​−yj​∣ 千米。

Shichikuji 希望以尽可能少的钱完成这项工作,因为在她看来,世界上除了钱什么都没有。然而,她小学五年级就去世了,所以她还不够聪明。因此,这位新任驻守神明向你寻求帮助。

你需要为 Shichikuji 提供以下信息:为所有城市供电所需的最小日元数、在哪些城市建造发电站,以及需要建立哪些连接。

如果存在多种选择城市和连接方式使得总花费最小,则输出任意一种即可。

输入格式

输入的第一行包含一个整数 n(1≤n≤2000),表示城市的数量。

接下来 n 行,每行包含两个用空格分隔的整数 xi​(1≤xi​≤106)和 yi​(1≤yi​≤106),表示第 i 个城市的坐标。

下一行包含 n 个用空格分隔的整数 c1​,c2​,…,cn​(1≤ci​≤109),表示在第 i 个城市建造发电站的费用。

最后一行包含 n 个用空格分隔的整数 k1​,k2​,…,kn​(1≤ki​≤109)。

输出格式

第一行输出一个整数,表示为所有城市供电所需的最小日元数。

第二行输出一个整数 v,表示需要建造发电站的城市数量。

第三行输出 v 个用空格分隔的整数,表示建造发电站的城市编号。每个编号应在 1 到 n 之间,且互不相同。编号顺序任意。

接下来一行输出一个整数 e,表示需要建立的连接数量。

最后输出 e 行,每行包含两个整数 a 和 b(1≤a,b≤n,a=b),表示需要在城市 a 和城市 b 之间建立连接。每对无序城市对最多出现一次(即对于每个 (a,b),不应有重复的 (a,b) 或 (b,a))。输出顺序任意。

如果存在多种选择城市和连接方式使得总花费最小,则输出任意一种即可。

显示翻译

题意翻译

输入输出样例

输入 #1复制

3
2 3
1 1
3 2
3 2 3
3 2 3

输出 #1复制

8
3
1 2 3 
0

输入 #2复制

3
2 1
1 2
3 3
23 2 23
3 2 3

输出 #2复制

27
1
2 
2
1 2
2 3

说明/提示

对于样例给出的答案,可参考下图(绿色为有发电站的城市,蓝色为其他城市,红色为电线):

对于第一个样例,在所有城市建造发电站的总费用为 3+2+3=8。可以证明,没有任何方案的花费低于 8 日元。

对于第二个样例,在第 2 号城市建造发电站的费用为 2。连接城市 1 和城市 2 的费用为 2⋅(3+2)=10。连接城市 2 和城市 3 的费用为 3⋅(2+3)=15。因此总费用为 2+10+15=27。可以证明,没有任何方案的花费低于 27 日元。

由 ChatGPT 4.1 翻译

代码实现:

#include <bits/stdc++.h>
using namespace std;

const int MAX_NODE = 2005;  // 最大节点数量

// 快速输入结构体
struct FastInput {
    template <typename Type>
    FastInput & operator >> (register Type & value) {
        register int sign = 1; 
        value = 0; 
        register char ch = getchar();
        
        // 处理符号
        for (; !isdigit(ch); ch = getchar()) {
            if (ch == '-') sign = -sign;
        }
        
        // 处理数字
        for (; isdigit(ch); ch = getchar()) {
            value = (value << 1) + (value << 3) + (ch - '0');
        }
        
        value *= sign; 
        return *this;
    }
} input;

int totalNodes;               // 总节点数量
int powerStationCount;        // 直接建立电源的节点个数
long long costFactor[MAX_NODE];// 每个节点的代价因子K
long long xCoord[MAX_NODE];   // 节点的X坐标
long long yCoord[MAX_NODE];   // 节点的Y坐标
long long prevNode[MAX_NODE]; // 记录上一次更新该节点的节点,用于构建边
long long totalCost;          // 最后的总代价
long long minDist[MAX_NODE];  // 当前树到各个非树节点的最小代价
bool inTree[MAX_NODE];        // 记录节点是否已加入树中

int main() {
    input >> totalNodes;
    
    // 读取节点坐标
    for (register int i = 1; i <= totalNodes; i++) {
        input >> xCoord[i] >> yCoord[i];
    }
    
    // 读取直接建立电站的代价,初始化最小距离数组
    for (register int i = 1; i <= totalNodes; i++) {
        input >> minDist[i];
    }
    
    // 读取代价因子,初始化前置节点为0(表示直接连接电源)
    for (register int i = 1; i <= totalNodes; i++) {
        input >> costFactor[i];
        prevNode[i] = 0;
    }
    
    // Prim算法构建最小生成树
    for (register int step = 1; step <= totalNodes; step++) {
        // 寻找未加入树且距离最小的节点
        register long long minCost = 2147483640;
        register int selectedNode;
        
        for (register int i = 1; i <= totalNodes; i++) {
            if (!inTree[i] && minDist[i] < minCost) {
                minCost = minDist[i];
                selectedNode = i;
            }
        }
        
        // 将选中的节点加入树中
        inTree[selectedNode] = true;
        totalCost += minCost;
        
        // 如果前置节点是0,说明这是一个新的电站
        if (prevNode[selectedNode] == 0) {
            powerStationCount++;
        }
        
        // 更新其他节点到树的最小距离
        for (register int i = 1; i <= totalNodes; i++) {
            if (!inTree[i]) {
                // 计算连接到选中节点的代价
                long long connectionCost = (costFactor[i] + costFactor[selectedNode]) * 
                                         (abs(xCoord[selectedNode] - xCoord[i]) + 
                                          abs(yCoord[selectedNode] - yCoord[i]));
                
                // 如果新的连接代价更小,则更新
                if (minDist[i] > connectionCost) {
                    minDist[i] = connectionCost;
                    prevNode[i] = selectedNode;
                }
            }
        }
    }
    
    // 输出结果
    printf("%lld\n%d\n", totalCost, powerStationCount);
    
    // 输出建立电站的节点
    for (register int i = 1; i <= totalNodes; i++) {
        if (prevNode[i] == 0) {
            printf("%d ", i);
        }
    }
    printf("\n");
    
    // 输出边的数量和具体边
    printf("%d\n", totalNodes - powerStationCount);
    for (register int i = 1; i <= totalNodes; i++) {
        if (prevNode[i] != 0) {
            printf("%lld %d\n", prevNode[i], i);
        }
    }
    
    return 0;
}
 

http://www.dtcms.com/a/344316.html

相关文章:

  • 雷达图教程:何时适用,何时无效,以及如何正确使用
  • 小智ai+mcp+n8n的智能组合
  • Matplotlib 可视化大师系列(三):plt.bar() 与 plt.barh() - 清晰对比的柱状图
  • 计算机组成原理(10) - 浮点数的表示
  • 全栈开发:从LAMP到云原生的技术革命
  • docker + nginx + pm2 部署前端项目和后端(nodejs)项目
  • setup 语法糖核心要点
  • 第二十八天:多项式求值问题
  • 决策树进阶学习笔记
  • 文件包含的学习笔记
  • ExcelUtils实现 设置内容 插入行 复制行列格式
  • Day11 数据统计 图形报表
  • 打造数字化资产管理新范式——资产管理系统实战体验
  • DIC技术极端环境案例分享:35MPa水下高压釜拉伸测试
  • Unity 自用帧同步架构分享
  • Python递归下降解析器深度解析:从原理到工程实践
  • layui.formSelects自定义多选组件在layer.open中使用、获取、复现
  • 2025年十大工程项目管理软件
  • 如何使用AI大语言模型解决生活中的实际小事情?
  • 【机器学习深度学习】LMDeploy的分布式推理实现
  • Laravel分布式全链路追踪实战
  • OpenCV 图像边缘检测
  • 设计模式之装饰模式
  • 技术革新:再互动平台如何以全链路数字化重构防伪溯源生态
  • 泵站远程监控与自动化控制系统:智慧泵房设备的创新实践
  • RLHF的定义
  • 无人机延时模块技术难点解析
  • 数字安全隐形基石:随机数、熵源与DRBG核心解析与技术关联
  • Kubernetes 构建高可用、高性能 Redis 集群
  • 服务器硬件中的磁盘SSD与HDD性能区别,以及分别适用于什么业务?