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 ...
随机推荐
- hdu 4512 (LCIS)
好久没写解题报告了,最近几周好忙...感觉是我进大学以来最忙的一段时间了,要给新生准备下周三比赛的题目,下周五要去南京赛区,回来之后马上就要期中考试了...不想挂科 额,很早之前就看过关于LCIS ...
- 超线程(Hyper-Threading)
运行方式 每个单位时间内,一个CPU只能处理一个线程(操作系统:thread),以这样的单位进行,如果想要在一单位时间内处理超过一个线程是不可能的,除非是有两个CPU的实体单元.双核心技术是将两个一样 ...
- 开源PaaS平台:Cloudify
Cloudify是gigaspaces公司推出的基于java的paas平台. refer to :http://timeson.iteye.com/blog/1699730
- Vue.之.安装
Vue.之.安装 第一步npm安装 首先:先从nodejs.org中下载nodejs 直到Finish完成安装. 打开控制命令行程序(CMD),检查是否正常 使用淘宝NPM 镜像 国内直接使用np ...
- PHP来控制Linux,ssh2来控制服务器端
注意:我们用PHP来控制Linux,php环境可以在windows也可以在linux,但是我们要控制的机器是一台linux(被控制的linux关闭selinux和firewalld). 如果php在l ...
- 阿里OSS-OSSFS
简介 OSSFS就以把OSS作为文件系统的一部分,能让你在linux系统中把OSS bucket挂载到本地文件系统中,实现数据的共享. 主要功能 ossfs 基于s3fs 构建,具有s3fs 的全部功 ...
- 【JZOJ4858】【GDOI2017模拟11.4】Walk
题目描述 在比特镇一共有n 个街区,编号依次为1 到n,它们之间通过若干条单向道路连接. 比特镇的交通系统极具特色,除了m 条单向道路之外,每个街区还有一个编码vali,不同街区可能拥有相同的编码.如 ...
- bzoj2752 高速公路
列式子: 如果把从i号收费站到i+1号收费站之间路段编号设为i. 假如查询l号收费站到r号收费站之间的期望值. $ Ans_{l,r} = \sum\limits_{i=l}^{r-1} v_i ...
- Servlet接口
ServletRequest接口 ServletRequest的对象用于向Servlet提供客户端请求信息,如内容类型,内容长度,参数名称和值,标题信息,属性等. RequestDispatcher接 ...
- 微信开发之web开发者工具
web开发者工具. 有任何疑问或建议请私信我,或者在评论区大家一起探讨. 概述 为帮助开发者更方便.更安全地开发和调试基于微信的网页,我们推出了 web 开发者工具.它是一个桌面应用,通过模拟微信客户 ...