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神仙在谈最小生成树 陈主力 ...
随机推荐
- 树莓派环境下使用python将h264格式的视频转为mp4
个人博客 地址:https://www.wenhaofan.com/a/20190430144809 下载安装MP4Box 命令行下执行以下指令安装MP4Box sudo apt-get inst ...
- Java工程师的必备知识点
最近参加了一次公司内部的调岗计划,打算加入一个更核心的部门.调岗计划有面试环节,为了不让自己搞砸,悉心准备了将近一个月,请教了百度和腾讯的有过面试官经验的大学同学,系统性的总结了Java工程师的核心知 ...
- LeetCode 第二题 Add Two Numbers 大整数加法 高精度加法 链表
题意 You are given two non-empty linked lists representing two non-negative integers. The digits are s ...
- VSCode常用插件之open in browser使用
更多VSCode插件使用请访问:VSCode常用插件汇总 open in browser安装完这个插件就可以在编辑器菜单右键html,在默认浏览器打开了,高级使用暂未了解,请自行其它文章学习
- Trie树相关博客
1. c++代码实现,包含删除操作:https://www.cnblogs.com/luxiaoxun/archive/2012/09/03/2668611.html 2. 一种典型实现及简单分析:h ...
- 1080 Graduate Admission
大致题意就是有N个学生,有M个学校,每个学校的名额都是正整数.每个学生可以填K个学校志愿,N个学生一起排名以后,排名高的学生先挑学校,不保护一志愿. 题目要求: 首先,把所有学生按总成绩SUM(GE+ ...
- LED Keychain-Ideal For Mass Promotions
Looking for something memorable to remind people of your business or nonprofit? Consider custom LED ...
- C++中局部变量的返回
在写 “根据中序和后序遍历顺序,构建树的问题” 时,原本这只是一个非常简单的问题,但是突然发现一直有错误.代码如下: node* get_root(int x1, int x2, int y1, in ...
- <if test="type == '0' ">没有进去这个判断的问题
在MyBatis的mapp文件中的if判断中是这样写的 <if test="type == '0' "> and so1.id = #{unitcode} </i ...
- android获取系统信息
连接手机,adb shell 进入 Android Shell 模式,输入 getprop 获取系统属性值 通过上面方法拿到属性名,然后通过下面方法获取到系统的属性值 /** * 获取build.pr ...