Codeforces Round #597 (Div. 2) D. Shichikuji and Power Grid 题解 最小生成树
题目链接:https://codeforces.com/contest/1245/problem/D
题目大意:
平面上有n座城市,第i座城市的坐标是 \(x[i], y[i]\) ,
你现在要给n城市供电,对于第i座城市,你可以选择两种方式给其供电:
- 建造一个发电站供电,这需要花费 \(c[i]\) ;
- 连一条连向城市j的电缆,这需要花费 \((|x[i]-x[j]|+|y[i]-y[j]|) \times (k[i]+k[j])\) 。
现在告诉你n以及 \(x[i], y[i], c[i], k[i]\) ,请你求出以下信息:
- 最少花费;
- 自己发电的城市数量;
- 自己发电的城市编号;
- 城市间连接电缆的数量;
- 所有连接有电缆的城市对。
解析思路:
这道题目就是一道最小生成树裸题。
首先,除了 \(n\) 个节点以外,我再开一个点 \(S\)(在我的程序中 \(S = 0\)),然后将 \(n\) 个点中的任意一点 \(i\) 分别向 \(S\) 连一条权值为 \(c[i]\) 的边,
\(n\) 个点两两之间(设两点编号为 \(i\) 和 \(j\))连一条权值为 \((|x[i]-x[j]| + |y[i]-y[j]|) \times (k[i]+k[j])\) 的边。
然后求这 \(n+1\) 个点的最小生成树。
整个图大致如下:

然后在最小生成树的 \(n\) 条边中,如果这条边的一个端点是 \(S\) ,那么另一个端点 \(i\) 就是自己建站的;
否则,这条边上的两点就是有连接关系的。
这样就能得到题目所要求的所有数据。
实现最小生成树可以使用kruskal或者prim算法,我这里使用kruskal实现。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
#define INF (1<<29)
const int maxn = 2020, maxm = 5000500;
struct Edge {
int u, v;
long long w;
Edge() {}
Edge(int _u, int _v, long long _w) { u = _u; v = _v; w = _w; }
} edge[maxm];
long long x[maxn], y[maxn], c[maxn], k[maxn], cost[maxn];
int n, cnt, f[maxn];
vector<int> res1;
vector<pair<int, int> > res2;
bool cmp(Edge a, Edge b) { return a.w < b.w; }
void init() {
for (int i = 0; i <= n; i ++) f[i] = i;
}
int func_find(int x) {
return x == f[x] ? x : f[x] = func_find(f[x]);
}
void func_union(int x, int y) {
int a = func_find(x), b = func_find(y);
f[a] = f[b] = f[x] = f[y] = min(a, b);
}
void kruskal() {
init();
sort(edge, edge+cnt, cmp);
int cc = 0;
long long ans = 0LL;
for (int i = 0; i < cnt; i ++) {
int u = edge[i].u, v = edge[i].v;
long long w = edge[i].w;
// printf("u = %d , v = %d , w = %lld\n", u, v, w);
if (func_find(u) != func_find(v)) {
ans += w;
cc ++;
if (!u) res1.push_back(v);
else if (!v) res1.push_back(u);
else res2.push_back(make_pair(u, v));
func_union(u, v);
if (cc == n) break;
}
}
cout << ans << endl;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> x[i] >> y[i];
for (int i = 1; i <= n; i ++) cin >> c[i];
for (int i = 1; i <= n; i ++) cin >> k[i];
for (int i = 1; i <= n; i ++) edge[cnt++] = Edge(0, i, c[i]);
for (int i = 1; i <= n; i ++) for (int j = 1; j <= n; j ++) edge[cnt++] = Edge(i, j, (abs(x[i]-x[j])+abs(y[i]-y[j]))*(k[i]+k[j]));
kruskal();
int sz = res1.size();
cout << sz << endl;
for (int i = 0; i < sz; i ++) {
if (i) putchar(' ');
cout << res1[i];
}
cout << endl;
sz = res2.size();
cout << sz << endl;
for (int i = 0; i < sz; i ++) {
cout << res2[i].first << " " << res2[i].second << endl;
}
return 0;
}
Codeforces Round #597 (Div. 2) D. Shichikuji and Power Grid 题解 最小生成树的更多相关文章
- Codeforces Round #597 (Div. 2) D. Shichikuji and Power Grid 最小生成树
D. Shichikuji and Power Grid</centerD.> Shichikuji is the new resident deity of the South Blac ...
- Codeforces Round #597 (Div. 2) D. Shichikuji and Power Grid
链接: https://codeforces.com/contest/1245/problem/D 题意: Shichikuji is the new resident deity of the So ...
- codeforces Codeforces Round #597 (Div. 2) D. Shichikuji and Power Grid
#include<bits/stdc++.h> using namespace std ; int n; struct City { int id; long long x,y; //坐标 ...
- Codeforces Round #597 (Div. 2)
A - Good ol' Numbers Coloring 题意:有无穷个格子,给定 \(a,b\) ,按以下规则染色: \(0\) 号格子白色:当 \(i\) 为正整数, \(i\) 号格子当 \( ...
- Codeforces Round #597 (Div. 2) C. Constanze's Machine
链接: https://codeforces.com/contest/1245/problem/C 题意: Constanze is the smartest girl in her village ...
- Codeforces Round #597 (Div. 2) B. Restricted RPS
链接: https://codeforces.com/contest/1245/problem/B 题意: Let n be a positive integer. Let a,b,c be nonn ...
- Codeforces Round #597 (Div. 2) A. Good ol' Numbers Coloring
链接: https://codeforces.com/contest/1245/problem/A 题意: Consider the set of all nonnegative integers: ...
- 计算a^b==a+b在(l,r)的对数Codeforces Round #597 (Div. 2)
题:https://codeforces.com/contest/1245/problem/F 分析:转化为:求区间内满足a&b==0的对数(解释见代码) ///求满足a&b==0在区 ...
- Codeforces Round #597 (Div. 2) F. Daniel and Spring Cleaning 数位dp
F. Daniel and Spring Cleaning While doing some spring cleaning, Daniel found an old calculator that ...
随机推荐
- 性能监控工具Munin
实际场景 公司产品需要观察Ubuntu主机性能,以衡量客户现场的产品是否能满足高频使用需求 选型 在比较了诸多工具之后,考虑时间成本因素,用了比较简单的Munin 安装步骤 1. apt-get in ...
- TypeScript高级类型
交叉类型 将多个类型合并成一个类型,去两个类型的并集.与继承的区别是,继承可以有自己的属性,而交叉没有. interface DogInterface { run():void } interface ...
- UI标签库专题五:JEECG智能开发平台 Tabs(选项卡父标签)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/zhangdaiscott/article/details/28956223 tools string ...
- Collection Iterator 迭代器
Collection c=new ArrayList(); c.add(123); //迭代器遍历集合 Iterator i=c.Iterator(); while(i.hasNext()) { Sy ...
- SPSS分析技术:无序多元Logistic回归模型;美国总统大选的预测历史及预测模型
SPSS分析技术:无序多元Logistic回归模型:美国总统大选的预测历史及预测模型 在介绍有序多元Logistic回归分析的理论基础时,介绍过该模型公式有一个非常重要的假设,就是自变量对因变量多个类 ...
- SpringBoot Cloud eureka 注册中心
SpringBoot Cloud是什么 Spring Cloud是一个分布式的整体解决方案. Spring Cloud 为开发者提供了在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一 ...
- Apache Camel继承Spring Boot 实现文件远程复制和转移
pom.xml <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-f ...
- 一个挺好用的自己写的小插件(用与把一般的图片转换成预制)——UNITY3D
首先 下载一个DLL文件,名字:System.Windows.Forms. 然后把这个文件放在资源目录,位置随便. 接着上代码 : using System.IO; using UnityEditor ...
- Linux进程管理(四、 进程终结)
进程调用exit()会终结当前进程,可以显式调用,也可以隐式: c语言main函数结束时编译器会自动加入exit调用 exit是系统调用,对应内核里的sys_exit() -> do_exit( ...
- docker-compose进入容器出现unable to find user root: no matching entries in passwd file
解决办法: 先docker-compose stop 容器,再docker-compose start 容器.虽然这样可以很快 解决问题,但并非长久之计.