赞
踩
题面链接: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;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。