• 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 时的线路造价。

    输出格式

    输出到标准输出中。

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

    样例输入

    1. 2 1 2
    2. 1 2
    3. 3 4
    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分题解: 

    1. #include
    2. using namespace std;
    3. using LL = long long;
    4. const LL inf = 1e18;
    5. int main(){
    6. ios::sync_with_stdio(false);
    7. cin.tie(0);cout.tie(0);
    8. int n, k, m;
    9. cin >> n >> m >> k;
    10. vectorint>> pcost(n, vector<int>(k));
    11. for(auto &i : pcost)
    12. for(auto &j : i)
    13. cin >> j;
    14. vectorint, 2>>> edge(n);
    15. vectorint, 2>> edges(m);
    16. vectorint>> ecost(m, vector<int>(k * k));
    17. for(int i = 0; i < m; ++ i){
    18. int u, v;
    19. cin >> u >> v;
    20. edges[i] = {u, v};
    21. edge[u].push_back({v, i});
    22. edge[v].push_back({u, i});
    23. for(auto &j : ecost[i])
    24. cin >> j;
    25. }
    26. if (n <= 6 && k <= 10){
    27. vector<int> used(n);
    28. LL ans = inf;
    29. LL tmp = 0;
    30. function<void(int)> dfs = [&](int x){
    31. if (x == n){
    32. LL back = tmp;
    33. for(int i = 0; i < m; ++ i){
    34. int u = edges[i][0], v = edges[i][1], id = i;
    35. int r = used[u] * k + used[v];
    36. tmp += ecost[id][r];
    37. }
    38. ans = min(ans, tmp);
    39. tmp = back;
    40. return;
    41. }
    42. for(int i = 0; i < k; ++ i){
    43. tmp += pcost[x][i];
    44. used[x] = i;
    45. dfs(x + 1);
    46. tmp -= pcost[x][i];
    47. }
    48. };
    49. dfs(0);
    50. cout << ans << '\n';
    51. }else if (m == n - 1){
    52. vector> dp(n, vector(k, 0));
    53. function<void(int, int)> dfs = [&](int u, int fa){
    54. for(auto e : edge[u]){
    55. int v = e[0], id = e[1];
    56. if (v == fa)
    57. continue;
    58. dfs(v, u);
    59. for(int i = 0; i < k; ++ i){
    60. LL tmp = inf;
    61. for(int j = 0; j < k; ++ j){
    62. int L = i, R = j;
    63. if (u != edges[id][0])
    64. swap(L, R);
    65. int r = L * k + R;
    66. tmp = min(tmp, dp[v][j] + pcost[v][j] + ecost[id][r]);
    67. }
    68. dp[u][i] += tmp;
    69. }
    70. }
    71. };
    72. dfs(0, 0);
    73. LL ans = inf;
    74. for(int i = 0; i < k; ++ i)
    75. ans = min(ans, dp[0][i] + pcost[0][i]);
    76. cout << ans << '\n';
    77. }else if (m == n){
    78. vector<int> id(n);
    79. iota(id.begin(), id.end(), 0);
    80. int ignore = 0;
    81. function<int(int)> findfa = [&](int x){
    82. return x == id[x] ? x : id[x] = findfa(id[x]);
    83. };
    84. for(int i = 0; i < m; ++ i){
    85. int u = edges[i][0], v = edges[i][1];
    86. int fu = findfa(u), fv = findfa(v);
    87. if (fu == fv){
    88. ignore = i;
    89. break;
    90. }
    91. id[fu] = fv;
    92. }
    93. vector> dp(n, vector(k, 0));
    94. LL ans = inf;
    95. int fixed = edges[ignore][0], st = edges[ignore][1];
    96. for(int col = 0; col < k; ++ col){
    97. for(auto &i : dp)
    98. fill(i.begin(), i.end(), 0);
    99. function<void(int, int)> dfs = [&](int u, int fa){
    100. for(auto e : edge[u]){
    101. int v = e[0], id = e[1];
    102. if (v == fa || id == ignore)
    103. continue;
    104. dfs(v, u);
    105. for(int i = 0; i < k; ++ i){
    106. if (u == fixed && i != col)
    107. continue;
    108. LL tmp = inf;
    109. for(int j = 0; j < k; ++ j){
    110. if (v == fixed && j != col)
    111. continue;
    112. int L = i, R = j;
    113. if (u != edges[id][0])
    114. swap(L, R);
    115. int r = L * k + R;
    116. tmp = min(tmp, dp[v][j] + pcost[v][j] + ecost[id][r]);
    117. }
    118. dp[u][i] += tmp;
    119. }
    120. }
    121. };
    122. dfs(st, st);
    123. for(int i = 0; i < k; ++ i){
    124. int L = i, R = col;
    125. if (st != edges[ignore][0])
    126. swap(L, R);
    127. int r = L * k + R;
    128. ans = min(ans, dp[st][i] + pcost[st][i] + ecost[ignore][r]);
    129. }
    130. }
    131. cout << ans << '\n';
    132. }else{
    133. vector<int> du(n);
    134. for(int i = 0; i < m; ++ i){
    135. int u = edges[i][0], v = edges[i][1];
    136. ++ du[u];
    137. ++ du[v];
    138. }
    139. int target = 0;
    140. for(int i = 0; i < n; ++ i){
    141. if (m - du[i] == n - 2){
    142. target = i;
    143. break;
    144. }
    145. }
    146. vector<int> forbid(n, 0);
    147. for(auto &e : edge[target]){
    148. int v = e[0];
    149. forbid[v] = 1;
    150. }
    151. int st = 0;
    152. while(st == target || forbid[st])
    153. ++ st;
    154. vector> dp(n, vector(k, 0));
    155. LL ans = inf;
    156. for(int col = 0; col < k; ++ col){
    157. for(auto &i : dp)
    158. fill(i.begin(), i.end(), 0);
    159. function<void(int, int)> dfs = [&](int u, int fa){
    160. for(auto e : edge[u]){
    161. int v = e[0], id = e[1];
    162. if (v == fa)
    163. continue;
    164. if (v != target)
    165. dfs(v, u);
    166. for(int i = 0; i < k; ++ i){
    167. LL tmp = inf;
    168. for(int j = 0; j < k; ++ j){
    169. if (v == target && j != col)
    170. continue;
    171. int L = i, R = j;
    172. if (u != edges[id][0])
    173. swap(L, R);
    174. int r = L * k + R;
    175. if (v == target){
    176. tmp = min(tmp, 1ll * ecost[id][r]);
    177. }else{
    178. tmp = min(tmp, dp[v][j] + pcost[v][j] + ecost[id][r]);
    179. }
    180. }
    181. dp[u][i] += tmp;
    182. }
    183. }
    184. };
    185. dfs(st, st);
    186. for(int i = 0; i < k; ++ i){
    187. ans = min(ans, dp[st][i] + pcost[st][i] + pcost[target][col]);
    188. }
    189. }
    190. cout << ans << '\n';
    191. }
    192. return 0;
    193. }

     运行结果:

  • 相关阅读:
    golang http客户端常用API:GET POST HEAD及自定义http客户端代码示例
    python folium 添加地图采样点及距离测量等属性
    IDEA 代码提交前流程及提交日志模板化
    [算法] 第二集 二叉树中的深度搜索
    操作系统——进程与线程の选择题整理
    SpringBoot整合MybatisPlus基本的增删改查,保姆级教程
    设计模式之单例模式
    从0-1 的 swagger
    Spring Boot的自动装配中的@ConditionalOnBean条件装配注解在Spring启动过程中,是如何保证处理顺序靠后的
    摄影后期色彩管理流程(Lightroom篇)
  • 原文地址:https://blog.csdn.net/weixin_53919192/article/details/134233401