CCF-CSP真题《202305-4 电力网络》思路+python,c++满分题解

2023-11-05 22:12

本文主要是介绍CCF-CSP真题《202305-4 电力网络》思路+python,c++满分题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 想查看其他题的真题及题解的同学可以前往查看:CCF-CSP真题附题解大全

试题编号:202305-4
试题名称:电力网络
时间限制:1.0s
内存限制:512.0MB
问题描述:

问题描述

西西艾弗岛电力公司需要修建一套电网对岛上的众多城镇进行供电。电网设施包括建造在城镇中的变电站,与建造在城镇间的输电线路。根据前期的考察结果,电力公司已经确定了哪些城镇之间需要建造输电线路,以使得所有城镇能够被连接成一个电力网络。每座城镇只需要建造一个变电站,却都向电力公司提供了多个建造候选地址。对于每个城镇,不同候选地址的变电站造价不同;对于城镇间的输电线路,其造价也会随着两端变电站的候选地址的变化而变化。因此,电力公司想要知道,在所有候选地址的组合中,电网的总造价(变电站造价加上输电线路造价)最低是多少。

输入格式

从标准输入读入数据。

输入的第一行包括三个正整数 N、M、K。表示一共有 N 座城镇,需要建造 M 条输电线路,每座城镇都提供了 K 个变电站候选地址。

接下来输入 N 行,每行表示一个城镇。每行包含 K 个整数,表示该城镇不同候选地址的变电站造价。

接下来 M 行,每行表示一条输电线路,包含 K2+2 个整数。前两个整数表示该输电线路两端的城镇,范围是 [0, N)。第三个整数开始是大小为 K×K 的矩阵 T 的行主序存储形式。Tij 表示当输电线路的第一个端点选择候选地址 i,第二个端点选择候选地址 j 时的线路造价。

输出格式

输出到标准输出中。

输出包含一行,这一行有一个整数,表示电网的最低总造价。

样例输入

2 1 2
1 2
3 4
0 1 1 2 3 4

Data

样例输出

5

Data

样例说明

城镇 0 与城镇 1 均选择了 0 号地址建造变电站。

子任务

对于全部数据,保证由城镇与输电线路构成的图是无向无重边无自环的连通图,保证单个变电站与单条线路的造价均不超过 1000。

对于 20% 的数据,保证 N≤6,K≤10。

对于另外 20% 的数据,保证 N≤104,K≤10,M=N−1。

对于另外 20% 的数据,保证 N≤104,K≤10,M=N。

对于另外 20% 的数据,保证 N≤104,K≤10。图中存在两个节点 S、D,保证全图去除 D 节点和与 D 节点相连的边后,可以构成以 S 节点为根的一棵树,而且所有与 D 相连的节点都属于这棵树的叶子节点。

对于最后 20% 的数据,保证 N≤104,K≤10,且度数大于 2 的节点数量 ≤6。

真题来源:电力网络

感兴趣的同学可以如此编码进去进行练习提交

c++ 80分题解: 

#include <bits/stdc++.h>
using namespace std;
using LL = long long;const LL inf = 1e18;int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n, k, m;cin >> n >> m >> k;vector<vector<int>> pcost(n, vector<int>(k));for(auto &i : pcost)for(auto &j : i)cin >> j;vector<vector<array<int, 2>>> edge(n);vector<array<int, 2>> edges(m);vector<vector<int>> ecost(m, vector<int>(k * k));for(int i = 0; i < m; ++ i){int u, v;cin >> u >> v;edges[i] = {u, v};edge[u].push_back({v, i});edge[v].push_back({u, i});for(auto &j : ecost[i])cin >> j;}if (n <= 6 && k <= 10){vector<int> used(n);LL ans = inf;LL tmp = 0;function<void(int)> dfs = [&](int x){if (x == n){LL back = tmp;for(int i = 0; i < m; ++ i){int u = edges[i][0], v = edges[i][1], id = i;int r = used[u] * k + used[v];tmp += ecost[id][r];}ans = min(ans, tmp);tmp = back;return;}for(int i = 0; i < k; ++ i){tmp += pcost[x][i];used[x] = i;dfs(x + 1);tmp -= pcost[x][i];}};dfs(0);cout << ans << '\n';}else if (m == n - 1){vector<vector<LL>> dp(n, vector<LL>(k, 0));function<void(int, int)> dfs = [&](int u, int fa){for(auto e : edge[u]){int v = e[0], id = e[1];if (v == fa)continue;dfs(v, u);for(int i = 0; i < k; ++ i){LL tmp = inf;for(int j = 0; j < k; ++ j){int L = i, R = j;if (u != edges[id][0])swap(L, R);int r = L * k + R;tmp = min(tmp, dp[v][j] + pcost[v][j] + ecost[id][r]);}dp[u][i] += tmp;}}};dfs(0, 0);LL ans = inf;for(int i = 0; i < k; ++ i)ans = min(ans, dp[0][i] + pcost[0][i]);cout << ans << '\n';}else if (m == n){vector<int> id(n);iota(id.begin(), id.end(), 0);int ignore = 0;function<int(int)> findfa = [&](int x){return x == id[x] ? x : id[x] = findfa(id[x]);};for(int i = 0; i < m; ++ i){int u = edges[i][0], v = edges[i][1];int fu = findfa(u), fv = findfa(v);if (fu == fv){ignore = i;break;}id[fu] = fv;}vector<vector<LL>> dp(n, vector<LL>(k, 0));LL ans = inf;int fixed = edges[ignore][0], st = edges[ignore][1];for(int col = 0; col < k; ++ col){for(auto &i : dp)fill(i.begin(), i.end(), 0);function<void(int, int)> dfs = [&](int u, int fa){for(auto e : edge[u]){int v = e[0], id = e[1];if (v == fa || id == ignore)continue;dfs(v, u);for(int i = 0; i < k; ++ i){if (u == fixed && i != col)continue;LL tmp = inf;for(int j = 0; j < k; ++ j){if (v == fixed && j != col)continue;int L = i, R = j;if (u != edges[id][0])swap(L, R);int r = L * k + R;tmp = min(tmp, dp[v][j] + pcost[v][j] + ecost[id][r]);}dp[u][i] += tmp;}}};dfs(st, st);for(int i = 0; i < k; ++ i){int L = i, R = col;if (st != edges[ignore][0])swap(L, R);int r = L * k + R;ans = min(ans, dp[st][i] + pcost[st][i] + ecost[ignore][r]);}}cout << ans << '\n';}else{vector<int> du(n);for(int i = 0; i < m; ++ i){int u = edges[i][0], v = edges[i][1];++ du[u];++ du[v];}int target = 0;for(int i = 0; i < n; ++ i){if (m - du[i] == n - 2){target = i;break;}}vector<int> forbid(n, 0);for(auto &e : edge[target]){int v = e[0];forbid[v] = 1;}int st = 0;while(st == target || forbid[st])++ st;vector<vector<LL>> dp(n, vector<LL>(k, 0));LL ans = inf;for(int col = 0; col < k; ++ col){for(auto &i : dp)fill(i.begin(), i.end(), 0);function<void(int, int)> dfs = [&](int u, int fa){for(auto e : edge[u]){int v = e[0], id = e[1];if (v == fa)continue;if (v != target)dfs(v, u);for(int i = 0; i < k; ++ i){LL tmp = inf;for(int j = 0; j < k; ++ j){if (v == target && j != col)continue;int L = i, R = j;if (u != edges[id][0])swap(L, R);int r = L * k + R;if (v == target){tmp = min(tmp, 1ll * ecost[id][r]);}else{tmp = min(tmp, dp[v][j] + pcost[v][j] + ecost[id][r]);}}dp[u][i] += tmp;}}};dfs(st, st);for(int i = 0; i < k; ++ i){ans = min(ans, dp[st][i] + pcost[st][i] + pcost[target][col]);}}cout << ans << '\n';}return 0;
}

 运行结果:

这篇关于CCF-CSP真题《202305-4 电力网络》思路+python,c++满分题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/352802

相关文章

使用Python创建一个能够筛选文件的PDF合并工具

《使用Python创建一个能够筛选文件的PDF合并工具》这篇文章主要为大家详细介绍了如何使用Python创建一个能够筛选文件的PDF合并工具,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录背景主要功能全部代码代码解析1. 初始化 wx.Frame 窗口2. 创建工具栏3. 创建布局和界面控件4

一文详解如何在Python中使用Requests库

《一文详解如何在Python中使用Requests库》:本文主要介绍如何在Python中使用Requests库的相关资料,Requests库是Python中常用的第三方库,用于简化HTTP请求的发... 目录前言1. 安装Requests库2. 发起GET请求3. 发送带有查询参数的GET请求4. 发起PO

Python与DeepSeek的深度融合实战

《Python与DeepSeek的深度融合实战》Python作为最受欢迎的编程语言之一,以其简洁易读的语法、丰富的库和广泛的应用场景,成为了无数开发者的首选,而DeepSeek,作为人工智能领域的新星... 目录一、python与DeepSeek的结合优势二、模型训练1. 数据准备2. 模型架构与参数设置3

Python进行PDF文件拆分的示例详解

《Python进行PDF文件拆分的示例详解》在日常生活中,我们常常会遇到大型的PDF文件,难以发送,将PDF拆分成多个小文件是一个实用的解决方案,下面我们就来看看如何使用Python实现PDF文件拆分... 目录使用工具将PDF按页数拆分将PDF的每一页拆分为单独的文件将PDF按指定页数拆分根据页码范围拆分

Python中常用的四种取整方式分享

《Python中常用的四种取整方式分享》在数据处理和数值计算中,取整操作是非常常见的需求,Python提供了多种取整方式,本文为大家整理了四种常用的方法,希望对大家有所帮助... 目录引言向零取整(Truncate)向下取整(Floor)向上取整(Ceil)四舍五入(Round)四种取整方式的对比综合示例应

python 3.8 的anaconda下载方法

《python3.8的anaconda下载方法》本文详细介绍了如何下载和安装带有Python3.8的Anaconda发行版,包括Anaconda简介、下载步骤、安装指南以及验证安装结果,此外,还介... 目录python3.8 版本的 Anaconda 下载与安装指南一、Anaconda 简介二、下载 An

Python自动化处理手机验证码

《Python自动化处理手机验证码》手机验证码是一种常见的身份验证手段,广泛应用于用户注册、登录、交易确认等场景,下面我们来看看如何使用Python自动化处理手机验证码吧... 目录一、获取手机验证码1.1 通过短信接收验证码1.2 使用第三方短信接收服务1.3 使用ADB读取手机短信1.4 通过API获取

python安装whl包并解决依赖关系的实现

《python安装whl包并解决依赖关系的实现》本文主要介绍了python安装whl包并解决依赖关系的实现,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录一、什么是whl文件?二、我们为什么需要使用whl文件来安装python库?三、我们应该去哪儿下

Python脚本实现图片文件批量命名

《Python脚本实现图片文件批量命名》这篇文章主要为大家详细介绍了一个用python第三方库pillow写的批量处理图片命名的脚本,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言源码批量处理图片尺寸脚本源码GUI界面源码打包成.exe可执行文件前言本文介绍一个用python第三方库pi

Python中多线程和多进程的基本用法详解

《Python中多线程和多进程的基本用法详解》这篇文章介绍了Python中多线程和多进程的相关知识,包括并发编程的优势,多线程和多进程的概念、适用场景、示例代码,线程池和进程池的使用,以及如何选择合适... 目录引言一、并发编程的主要优势二、python的多线程(Threading)1. 什么是多线程?2.