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 ...
随机推荐
- LintCode刷题笔记--Longest Increasing Subsequence
标签: 动态规划 描述: Given a sequence of integers, find the longest increasing subsequence (LIS). You code s ...
- hive行转列的高级用法later view explode
先贴出一个示例: 参考链接
- vue渲染学生信息
渲染学生信息 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- 客户端connect返回错误显示No route to host
务器程序运行起来后,客户端connect返回错误显示No route to host,但是两台机子能ping通 是firewall的问题, services iptables stop应该就ok了
- NodeJs的简介及安装
首先 分享一下NodeJs的应用场景吧: Web聊天室(IM):Express + Socket.io socket.io一个是基于Nodejs架构体系的,支持websocket的协议用于时时通信的一 ...
- R语言实现分层抽样(Stratified Sampling)以iris数据集为例
R语言实现分层抽样(Stratified Sampling)以iris数据集为例 1.观察数据集 head(iris) Sampling)以iris数据集为例"> 选取数据集中前6个 ...
- Directx11教程(13) D3D11管线(1)
原文:Directx11教程(13) D3D11管线(1) 从本篇教程开始,我们暂停代码的学习,先来了解一下D3D11的管线,这些管线不涉及具体的硬件,而是着重于理解能够支持D3D11的管 ...
- Linux进程管理(四、 进程终结)
进程调用exit()会终结当前进程,可以显式调用,也可以隐式: c语言main函数结束时编译器会自动加入exit调用 exit是系统调用,对应内核里的sys_exit() -> do_exit( ...
- 使用PHP类TCPDF生成PDF文档
转自:http://www.blhere.com/1180.html 这两天遇到一个项目中,需要php自动处理生成pdf文档.在网上找了好几个类,最后决定使用TCPDF,使用的时候真是发现这个类真是强 ...
- LeetCode191 Number of 1 Bits. LeetCode231 Power of Two. LeetCode342 Power of Four
位运算相关 三道题 231. Power of Two Given an integer, write a function to determine if it is a power of two. ...