codeforces 1245D(最小生成树)
题面链接:https://codeforces.com/problemset/problem/1245/D
题意大概是给你一些城市的坐标,可以在城市中建立发电站,也可以让某个城市和已经建好发电站的城市连接,保证在这两种操作下使得所有的城市供电,在城市建发电站需要花费Ci,城市a和城市b连接需要花费(|Xa-Xb| + |Ya-Yb| )*(Ka+Kb),求最小的花费让所有城市通电。
思路:首先建立一个源点,连接各个城市,边权就是建发电站费用Ci,若选择此边则表示是在该城市建了发电站。
剩下的城市互相按照题意要求建边,建完全图。
最终模型就抽象成求最小生成树,用克鲁斯卡尔算法跑一下即可
AC代码:
#include<iostream>
#include<vector>
#include<set>
#include<cstdio>
#include<algorithm>
#define maxn 2005
using namespace std;
typedef long long ll;
struct node{
int from,to;
ll cost;
}e[maxn*maxn];//存储边的信息
int father[maxn];
int cnt,N,city;
vector<int> sta;//存建发电站的城市
vector<int> citya,cityb;//存储a b城市表示ab之间有电线
bool cmp(node a,node b){//比较函数
return a.cost < b.cost ;
}
void init(){//初始化
cnt = 0;
for(int i = 0;i<=N;i++){
father[i] = i;
}
}
int find(int x){//寻找根
if(x == father[x]) return x;
return father[x] = find(father[x]);
}
bool same(int x,int y){//判断是否在一个集合
return find(x)==find(y);
}
void unionSet(int x,int y){ //并查集合并
int u = find(x),v = find(y);
if(u==v) return ;
father[u] = v;
}
long long kruskal(){ //求最小生成树
ll res = 0;
std::sort(e,e+cnt,cmp);
for(int i = 0;i<cnt;i++){
if(same(e[i].from,e[i].to )) continue;
unionSet(e[i].from ,e[i].to );
if(e[i].from == 0 || e[i].to == 0){//判一下是否在城市建了发电站(利用源点判断)
if(e[i].from == 0) sta.push_back(e[i].to );
else sta.push_back(e[i].from);
}
else{//如果不是,存一些a,b两座连接的城市
citya.push_back(e[i].from ),cityb.push_back(e[i].to);
}
res+=e[i].cost ;
}
return res;
}
void addedge(int u,int v,ll C){ //建边操作
e[cnt].from = u,e[cnt].to = v,e[cnt].cost = C;
cnt++;
}
int main(){
cin>>N;
init();
vector<long long> vx,vy;
vector<long long> c,k;
for(int i = 0;i<N;i++){
int x,y;cin>>x>>y;
vx.push_back(x),vy.push_back(y);
}
for(int i = 0;i<N;i++){
ll tc;cin>>tc;
c.push_back(tc);
}
for(int i = 0;i<N;i++){
ll tk;cin>>tk;
k.push_back(tk);
}
for(int i = 0;i<N;i++){//建立源点,和各个城市连接
addedge(0,i+1,c[i]);
}
for(int i = 0;i<N;i++){//城市和城市之间建完全图
for(int j = i+1;j<N;j++){
ll c = (abs(vx[i]-vx[j])+abs(vy[i]-vy[j]))*(k[i]+k[j]);
addedge(i+1,j+1,c);
}
}
ll ans = kruskal();
cout<<ans<<endl;
cout<<sta.size()<<endl;
for(int i = 0;i<sta.size();i++){
if(i==0) cout<<sta[i];
else cout<<" "<<sta[i];
}
cout<<endl;
cout<<citya.size()<<endl;
for(int i = 0;i<citya.size() ;i++){
cout<<citya[i]<<" "<<cityb[i]<<endl;
}
return 0;
}
codeforces 1245D(最小生成树)的更多相关文章
- [Codeforces 1245D] Shichikuji and Power Grid (最小生成树)
[Codeforces 1245D] Shichikuji and Power Grid (最小生成树) 题面 有n个城市,坐标为\((x_i,y_i)\),还有两个系数\(c_i,k_i\).在每个 ...
- CodeForces - 1245D(思维+最小生成树)
题意 https://vjudge.net/problem/CodeForces-1245D 已知一个平面上有 n 个城市,需要个 n 个城市均通上电 一个城市有电,必须在这个城市有发电站或者和一个有 ...
- codeForces 472D 最小生成树
题目大意:给出一个图中点的两两距离,问是否是一棵树,若是,求出平均边权最大的点 prim最小生成树,若原图是树,则最小生成树的距离就是原距离.否则不是. 搞出来树了,第二问随便dfs就好了. #inc ...
- Xor-MST CodeForces - 888G (最小生成树,分治)
大意: n结点无向完全图, 给定每个点的点权, 边权为两端点异或值, 求最小生成树
- Mobile Phone Network CodeForces - 1023F (最小生成树)
大意: 无向图, 其中k条边是你的, 边权待定, m条边是你对手的, 边权已知. 求如何设置边权能使最小生成树中, 你的边全被选到, 且你的边的边权和最大. 若有多棵最小生成树优先取你的边. 先将$k ...
- CodeForces 1245D Shichikuji and Power Grid
cf题面 解题思路 比赛过程中想了一个贪心--把所有城市按照自建代价排序,排在第一的城市肯定自建,之后依次判断排在后面的城市要自建还是要连接前面的.这么做WA13了(第一次忘开long longWA4 ...
- The Shortest Statement CodeForces - 1051F 最小生成树+并查集+LCA
题目描述 You are given a weighed undirected connected graph, consisting of n vertices and mm edges. You ...
- Abandoning Roads CodeForces - 1149D (最小生成树)
大意: 给定无向图, 边权只有两种, 对于每个点$x$, 输出所有最小生成树中, 点$1$到$x$的最短距离. 先将边权为$a$的边合并, 考虑添加边权为$b$的边. 每条路径只能经过每个连通块一次, ...
- 正睿OI国庆DAY2:图论专题
正睿OI国庆DAY2:图论专题 dfs/例题 判断无向图之间是否存在至少三条点不相交的简单路径 一个想法是最大流(后来说可以做,但是是多项式时间做法 旁边GavinZheng神仙在谈最小生成树 陈主力 ...
随机推荐
- laravel本地化扩展包的下载使用
1.下载扩展包 composer require caouecs/laravel-lang:~3.0 2.下载完成之后在根目录下的vendor中caouces\src下就是语言的扩展包 2.1我们复制 ...
- Codeforce 588A - Duff and Meat (贪心)
Duff is addicted to meat! Malek wants to keep her happy for n days. In order to be happy in i-th day ...
- 酸菜鱼的 DP动态规划 刷题记录
BZOJ1026: [SCOI2009]windy数 数位dp.很多小细节... 代码: #include <bits/stdc++.h> using namespace std; typ ...
- [SDOI2017] 新生舞会 - 二分图最大权匹配,分数规划,二分答案
有一个二分图,每个部都有 \(n\) 个点,每条边有两个参数 \(a_e, b_e\),求一种匹配,使得 \(\sum a_i / \sum b_i\) 最大 Solution 显然的分数规划,考虑二 ...
- promise的连缀写法
promise的连缀写法 以上写法相当于写了两个实例 promise.all() 1. promise.all() all这个方法是 promise 构造函数的成员不是实例对象成员,这个方法接受一个参 ...
- asp.net中正则表达式使用
一.限定符:限定符提供了一种简单方法,用于指定允许特定字符或字符集自身重复出现的次数.限定符始终引用限定符前(左边)的模式,通常是单个字符,除非使用括号创建模式组. (一)非显示限定符 1. *,描述 ...
- JavaScript的jQuery
JavaScript的jQuery 不通过JavaScript的原生代码,如document.getElementById("") 而是通过jQuery的$符号选择器. jQuer ...
- 算法竞赛入门经典第二版 竖式问题 P42
#include<bits/stdc++.h> using namespace std; int inset(char *s,int num) { //判断数字是否在数字集中 int le ...
- decimal与float和double的区别
一直很奇怪C#的预定义数据类型中为什么加了一个decimal,有float和double不就够了吗?今天来挖一挖. 浮点型 Name CTS Type De script ion Significan ...
- 创建JDBC六个步骤
JDBC库中所包含的API通常与数据库使用于: 连接到数据库 创建SQL或MySQL语句 在数据库中执行SQL或MySQL查询 查看和修改数据库中的数据记录 创建JDBC应用程序 建立一个JDBC应用 ...