题目链接: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. webpack学习之—— Plugins

    Plugins are the backbone of webpack! webpack 自身也是构建于你在 webpack 配置中用到的相同的插件系统之上! 插件目的在于解决 loader 无法实现 ...

  2. 如何正确的在Android中存储特定应用文件

    原文地址:How to Correctly Store App-Specific Files in Android Christophe Versieux (Waza_be)发表了一篇rant abo ...

  3. js数组求交集

    求两个数组的交集 var arr1 = [1,2,3]; var arr2 = [2,3,4]; var arr3; arr3 = arr1.filter(function(num) { return ...

  4. NOIP模拟 7.03

    Problem 1 抓牛(catchcow.cpp/c/pas) [题目描述] 农夫约翰被通知,他的一只奶牛逃逸了!所以他决定,马上出发,尽快把那只奶牛抓回来. 他们都站在数轴上.约翰在N(O≤N≤1 ...

  5. 初探uni-app

    第一步:下载 第二步:安装 第三步:创建项目 第四步:项目目录 项目运行 项目效果为 打包为原生App(云端) 运行打包 使用vue 效果如下,并不好看 使用代码如下 未完,待续.... 就是对着官网 ...

  6. npm run dev 和 npm run serve

    1.ERR引发的思考 创建好的 vue 项目直接执行 vue run dev 报错?运行 vue run serve 就可以启动...如下 npm run dev npm ERR! missing s ...

  7. Kubernetes 调度器实现初探

    Kubernetes 调度器 Kubernetes 是一个基于容器的分布式调度器,实现了自己的调度模块.在Kubernetes集群中,调度器作为一个独立模块通过pod运行.从几个方面介绍Kuberne ...

  8. request.getcontextPath() 详解 和 <link标签>

    classpath:只会到你的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找. 绝对路径: D:\磊弟资料\最代码\智父子考试 ...

  9. LaTeX Error: File `slashbox.sty' not found. 解决办法

    从这里下载对应的文件,解压后把文件放在C:\Latex\2018\texmf-dist\tex\latex 中. 再打开cmd命令窗口,输入texhash刷新!

  10. docker无法删除镜像,Error: No such container,附docker常用命令

    最近打算删除掉docker镜像但是发现有几个镜像就是删除不了,加了-f强制删除也不行,一直报Error: No such container的错误,最后终于找到了办法直接删除文件,步骤如下: 切换到r ...