Codeforces Round #597 (Div. 2)D(最小生成树)

/*每个点自己建立一座发电站相当于向超级源点连一条长度为c[i]的边,连电线即为(k[i]+k[j])*两点间曼哈顿距离,跑最小生成树(prim适用于稠密图,kruscal适用于稀疏图)*/

#define HAVE_STRUCT_TIMESPEC
#include<bits/stdc++.h>
using namespace std;
int fa[2007];
int x[2007],y[2007];
int c[2007],k[2007];
long long m[2007][2007];
vector<pair<long long,pair<int,int> > >edge;
vector<int>ans_point;
vector<pair<int,int> >ans_edge;
int fi(int x){
return fa[x]==x?x:fa[x]=fi(fa[x]);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n;
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){
m[0][i]=c[i];
fa[i]=i;
edge.push_back({c[i],make_pair(0,i)});
}
for(int i=1;i<=n;++i){
for(int j=i+1;j<=n;++j){
long long tamp=1ll*(k[i]+k[j])*(abs(x[i]-x[j])+abs(y[i]-y[j]));
edge.push_back({tamp,make_pair(i,j)});
}
}
sort(edge.begin(),edge.end());
long long ans=0;
for(int i=0;i<edge.size();++i){
long long tamp=edge[i].first;
int x=edge[i].second.first;
int y=edge[i].second.second;
if(fi(x)==fi(y))
continue;
ans+=tamp;
if(!x)
ans_point.push_back(y);
else
ans_edge.push_back({x,y});
fa[fi(y)]=x;
}
cout<<ans<<"\n";
cout<<ans_point.size()<<"\n";
for(int i=0;i<ans_point.size();++i)
cout<<ans_point[i]<<" ";
cout<<"\n";
cout<<ans_edge.size()<<"\n";
for(int i=0;i<ans_edge.size();++i)
cout<<ans_edge[i].first<<" "<<ans_edge[i].second<<"\n";
return 0;
}

原文地址:https://www.cnblogs.com/ldudxy/p/11832582.html

时间: 2024-09-30 21:59:31

Codeforces Round #597 (Div. 2)D(最小生成树)的相关文章

Codeforces Round #597 (Div. 2) A. Good ol&#39; Numbers Coloring

链接: https://codeforces.com/contest/1245/problem/A 题意: Consider the set of all nonnegative integers: 0,1,2,-. Given two integers a and b (1≤a,b≤104). We paint all the numbers in increasing number first we paint 0, then we paint 1, then 2 and so on. Ea

题解Codeforces Round #597 (Div. 2)

A:送分,裸的gcd. 1 #include<stdio.h> 2 #define il inline 3 #define it register int 4 int T,a,b,d; 5 il void gcd(int a,int b){ 6 if(!b){d=a;return;} 7 gcd(b,a%b); 8 } 9 il void fr(int &num){ 10 num=0;char c=getchar();int p=1; 11 while(c<'0'||c>'

Codeforces Round #597 (Div. 2) D. Shichikuji and Power Grid

题意: 二维平面上n个点,每个点可以建厂,也可以与其他点连边,建厂花费为\(c_i\),与j连边花费为\((k_i+k_j)*dis(i,j)\),dis为两点之间的欧式距离,求让每个点都通电的最小花费与方案 思路: 维护使这个点通电的花费的优先队列,一开始先把建厂放进去,然后每次拿出最小花费的点i,再用i去更新与i建路的花费(有点像最小生成树). #include<bits/stdc++.h> #define ll long long #define pii pair<int,int&

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 nonnegative integers such that a+b+c=n. Alice and Bob are gonna play rock-paper-scissors n times. Alice knows the sequences of hands that Bob will play. H

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; //坐标 long long cc,kk; //自建的花费,连线的花费 bool self;//是否建站 int fa;//连线的站 bool operator < (const City & a)const { return cc<a.cc; } } c[2005]; int main() {

Codeforces Round #597 (Div. 2) E. Hyakugoku and Ladders 概率dp

E. Hyakugoku and Ladders Hyakugoku has just retired from being the resident deity of the South Black Snail Temple in order to pursue her dream of becoming a cartoonist. She spent six months in that temple just playing "Cat's Cradle" so now she w

# Codeforces Round #529(Div.3)个人题解

Codeforces Round #529(Div.3)个人题解 前言: 闲来无事补了前天的cf,想着最近刷题有点点怠惰,就直接一场cf一场cf的刷算了,以后的题解也都会以每场的形式写出来 A. Repeating Cipher 传送门 题意:第一个字母写一次,第二个字母写两次,依次递推,求原字符串是什么 题解:1.2.3.4,非常明显的d=1的等差数列,所以预处理一个等差数列直接取等差数列的每一项即可 代码: #include<bits/stdc++.h> using namespace s

Codeforces Round #536 (Div. 2)

目录 Codeforces Round #536 (Div. 2) A 题目大意 题解 卡点 C++ Code: B 题目大意 题解 卡点 C++ Code: C 题目大意 题解 卡点 C++ Code: D 题目大意 题解 卡点 C++ Code: E 题目大意 题解 卡点 C++ Code: F 题目大意 题解 卡点 C++ Code: Codeforces Round #536 (Div. 2) A 题目大意 给你一个\(n\times n(n\leqslant500)\)的矩阵,只包含.

Codeforces Round #535 (Div. 3) 题解

Codeforces Round #535 (Div. 3) 题目总链接:https://codeforces.com/contest/1108 太懒了啊~好久之前的我现在才更新,赶紧补上吧,不能漏掉了. A. Two distinct points 题意: 给出两个区间的左右边界,输出两个数,满足两个数分别在两个区间内且这两个数不相等. 题解: 直接输出左端点然后判断一下就行了. 代码如下: #include <bits/stdc++.h> using namespace std; type