题目链接: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 题解 最小生成树的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 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; //坐标 ...

  4. Codeforces Round #597 (Div. 2)

    A - Good ol' Numbers Coloring 题意:有无穷个格子,给定 \(a,b\) ,按以下规则染色: \(0\) 号格子白色:当 \(i\) 为正整数, \(i\) 号格子当 \( ...

  5. Codeforces Round #597 (Div. 2) C. Constanze's Machine

    链接: https://codeforces.com/contest/1245/problem/C 题意: Constanze is the smartest girl in her village ...

  6. 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 ...

  7. Codeforces Round #597 (Div. 2) A. Good ol' Numbers Coloring

    链接: https://codeforces.com/contest/1245/problem/A 题意: Consider the set of all nonnegative integers: ...

  8. 计算a^b==a+b在(l,r)的对数Codeforces Round #597 (Div. 2)

    题:https://codeforces.com/contest/1245/problem/F 分析:转化为:求区间内满足a&b==0的对数(解释见代码) ///求满足a&b==0在区 ...

  9. 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 ...

随机推荐

  1. JavaScript 防抖和节流

    1. 概述 1.1 说明 在项目过程中,经常会遇到一个按钮被多次点击并且多次调用对应处理函数的问题,而往往我们只需去调用一次处理函数即可.有时也会遇到需要在某一规则内有规律的去触发对应的处理函数,所以 ...

  2. js正则表达式常见规则整理

    验证数字的正则表达式集 验证数字:^[0-9]*$ 验证n位的数字:^\d{n}$ 验证至少n位数字:^\d{n,}$ 验证m-n位的数字:^\d{m,n}$ 验证零和非零开头的数字:^(0|[1-9 ...

  3. 2019-1-29-Sublime-Text-安装中文、英文字体

    title author date CreateTime categories Sublime Text 安装中文.英文字体 lindexi 2019-01-29 16:35:25 +0800 201 ...

  4. 【水滴石穿】react-native-app

    项目地址:https://github.com/WQone/react-native-app 这个是一个非常优秀的小姐姐写的,希望大家能够以她为榜样,一起加油进步呀- 先看效果 分析package.j ...

  5. Xdebug步骤

    谷歌浏览器安装xdebug cd  /etc/php/7.2/fpm/conf.d 重启sudo service php7.1-fpm restart   (注意 php版本) 重启编辑器

  6. OSGi教程:Resource API Specification

    此教程基于OSGi Core Release 7 OSGi Resource API规范 详细内容上面英文教程有详细解答 下面主要是一些个人见解,若有不当之处,欢迎指出: Resource:就是能够被 ...

  7. left join table_a on ...like...

  8. Android Binder设计与实现 – 设计篇

    摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder ...

  9. NLP+2vec︱认识多种多样的2vec向量化模型

    1.word2vec 耳熟能详的NLP向量化模型. Paper: https://papers.nips.cc/paper/5021-distributed-representations-of-wo ...

  10. kubernetes1.4新特性:支持Docker新特性

    (一)背景资料 在Kubernetes1.2中这个第三方组件就是go-dockerclient,这是一个GO语言写的docker客户端,支持Dockerremote API,这个项目在https:// ...