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

  1. [Codeforces 1245D] Shichikuji and Power Grid (最小生成树)

    [Codeforces 1245D] Shichikuji and Power Grid (最小生成树) 题面 有n个城市,坐标为\((x_i,y_i)\),还有两个系数\(c_i,k_i\).在每个 ...

  2. CodeForces - 1245D(思维+最小生成树)

    题意 https://vjudge.net/problem/CodeForces-1245D 已知一个平面上有 n 个城市,需要个 n 个城市均通上电 一个城市有电,必须在这个城市有发电站或者和一个有 ...

  3. codeForces 472D 最小生成树

    题目大意:给出一个图中点的两两距离,问是否是一棵树,若是,求出平均边权最大的点 prim最小生成树,若原图是树,则最小生成树的距离就是原距离.否则不是. 搞出来树了,第二问随便dfs就好了. #inc ...

  4. Xor-MST CodeForces - 888G (最小生成树,分治)

    大意: n结点无向完全图, 给定每个点的点权, 边权为两端点异或值, 求最小生成树

  5. Mobile Phone Network CodeForces - 1023F (最小生成树)

    大意: 无向图, 其中k条边是你的, 边权待定, m条边是你对手的, 边权已知. 求如何设置边权能使最小生成树中, 你的边全被选到, 且你的边的边权和最大. 若有多棵最小生成树优先取你的边. 先将$k ...

  6. CodeForces 1245D Shichikuji and Power Grid

    cf题面 解题思路 比赛过程中想了一个贪心--把所有城市按照自建代价排序,排在第一的城市肯定自建,之后依次判断排在后面的城市要自建还是要连接前面的.这么做WA13了(第一次忘开long longWA4 ...

  7. The Shortest Statement CodeForces - 1051F 最小生成树+并查集+LCA

    题目描述 You are given a weighed undirected connected graph, consisting of n vertices and mm edges. You ...

  8. Abandoning Roads CodeForces - 1149D (最小生成树)

    大意: 给定无向图, 边权只有两种, 对于每个点$x$, 输出所有最小生成树中, 点$1$到$x$的最短距离. 先将边权为$a$的边合并, 考虑添加边权为$b$的边. 每条路径只能经过每个连通块一次, ...

  9. 正睿OI国庆DAY2:图论专题

    正睿OI国庆DAY2:图论专题 dfs/例题 判断无向图之间是否存在至少三条点不相交的简单路径 一个想法是最大流(后来说可以做,但是是多项式时间做法 旁边GavinZheng神仙在谈最小生成树 陈主力 ...

随机推荐

  1. C#中怎样获取System.Drawing.Color的所有颜色对象并存到数组中

    场景 需要在生成一组多条曲线时,随机从一颜色数组中取颜色,至少一百种颜色以上. 而System.Drawing.Color自带140多种颜色 那么怎样将其自带的颜色对象取出并存在数组中. 注: 博客主 ...

  2. c# 调用c++类库控制usb继电器

    网上找不到调用此类库的文章,简单写一下,以备后用. 下面是封装后的调用c++类库的类 public class UsbRelayDeviceHelper { /// <summary> / ...

  3. cookie、session和application

    https://cloud.tencent.com/developer/article/1493869 前言: 一直想写一篇关于cookie和session的博客,由于种种原因,一直没有整理,这不,今 ...

  4. SVN之TortoiseSVN使用02

    TortoiseSVN常用操作和安装eclipse的svn插件 一.关于TortoiseSVN的介绍 1. 安装TortoiseSVN图像化操作软件,便于操作SVN! 如图有两种版本的,一个是32位, ...

  5. 展开折叠效果 height未知 transition无效

    展开折叠效果,没有设置height时 transition 不起作用 可以设置max-height .default { max-height: 500px; transition: all 1000 ...

  6. Python中需要注意的一些小坑

    Python小知识 # a = a + b /a += b 有时是不一样的​ a=[1,2,3] b = a a = a + [4,5,6] ​ # a=[1,2,3] # b = a # a += ...

  7. nginx ip配置反向代理为本地域名

    #### gitlab反向代理 server { listen ; server_name gitlab.hp.com; location / { proxy_pass http://192.168. ...

  8. php单例模式封装数据库操作类增删改查

    <?php//三私一公 单例class Db{ //数据库连接对象 private static $instance; private static $table_name; private $ ...

  9. 关于setTimeout的妙用

    定义 在指定的延迟时间之后调用一个函数或执行一个代码片段 这个是setTimeout最主要的功能,但也是很坑的地方,首先javascript其实是运行在单线程的环境下,意味者定时器会在未来的某个时间支 ...

  10. redis相关问题记录

    问题:无法在redis自行set操作 错误信息:(error) MISCONF Redis is configured to save RDB snapshots, but is currently ...