CF1245D Shichikuji and Power Grid
题意:
已知一个平面上有 n 个城市,需要个 n 个城市均通上电
一个城市有电,必须在这个城市有发电站或者和一个有电的城市用电缆相连
在一个城市建造发电站的代价是 c[i]
i 和 j两个城市相连的代价是 k[i]+k[j] 乘上两者的曼哈顿距离
求最小代价的方案
输入:
第一行为城市个数
下面是每个城市的坐标
下面是建造发电站的代价 c[i]
下面是每个城市连线的系数 k[i]
输出:
一个为最小代价
建造发电站的城市数,和每个城市
连线的条数,和每条连线
任意一种即可,输出顺序任意
题解:
如果没有发电站,其实就是求最小生成树,如何能兼顾发电站的情况?我可以建一个源点,指向所有的点,代价为发电站,这样跑最小生成树,保证所有点连通,其至少有一个是发电站
代码:
#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const ll INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...);
}
template <typename T> inline void write(T x)
{if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef ONLINE_JUDGE
#elsestartTime= clock();freopen("in.txt", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const ll maxn=4e5+9;ll c[maxn],k[maxn];
struct nw{ll x,y;
}a[maxn];
ll fa[maxn];
ll find(ll x){if(fa[x]==x)return x;else return fa[x]=find(fa[x]);
}
struct node{ll u,v,w;
}edge[7000000];
ll ans=0;
ll tot=0;
ll n;
vector<ll>vec;
vector<PII>V;
void krusal(){ll total=0;for(ll i=1;i<=tot;i++){ll u=find(edge[i].u);ll v=find(edge[i].v);if(u==v)continue;if(edge[i].v&&edge[i].u){V.push_back({edge[i].v,edge[i].u});}else {if(edge[i].u){vec.push_back(edge[i].u);}else {vec.push_back(edge[i].v);}}ans+=edge[i].w;fa[u]=v;total++;if(total==n-1+1)break;}
}
bool cmp(node a,node b){return a.w<b.w;
}
signed main()
{//rd_test();read(n);for(ll i=1;i<=n;i++){read(a[i].x,a[i].y);fa[i]=i;}for(ll i=1;i<=n;i++)read(c[i]);for(ll i=1;i<=n;i++)read(k[i]);for(ll i=1;i<=n;i++){for(ll j=i+1;j<=n;j++){ll w=(k[i]+k[j])*(abs(a[i].x-a[j].x)+abs(a[i].y-a[j].y));edge[++tot].u=i;edge[tot].v=j;edge[tot].w=w;}}for(ll i=1;i<=n;i++){edge[++tot].u=0;edge[tot].v=i;edge[tot].w=c[i];
// vec[0].push_back({i,c[i]});
// vec[i].push_back({0,c[i]});}sort(edge+1,edge+tot+1,cmp);krusal();ll id=0;cout<<ans<<endl;cout<<(ll)vec.size()<<endl;for(auto v:vec)cout<<v<<" ";if(vec.size())cout<<endl;cout<<V.size()<<endl;for(auto it:V)cout<<it.first<<" "<<it.second<<endl; //Time_test();
}