description
为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里每座建筑都连上互联网,方便未来随时随地网购农药。
他的农庄很大,有N 座建筑,但地理位置偏僻,网络信号很差。
一座建筑有网,当且仅当满足以下至少一个条件:
1、给中国移动交宽带费,直接连网,花费为A。
2、向另外一座有网的建筑,安装共享网线,花费为B×两者曼哈顿距离。
现在,农夫约已经统计出了所有建筑的坐标。他想知道最少要多少费用才能达到目的。
analysis
-
这题的思路和模型可以非常巧妙来转变
-
新加入一个点,从这个点向每一个点连一条权值为 A A A的边
-
剩余的点两两连一条边,然后直接做一次 M S T MST MST即可
-
可以感性理解,这样的边权和是最小的
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 1005
#define MAXM MAXN*MAXN
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define O3 __attribute__((optimize("-O3")))
using namespace std;
ll x[MAXN],y[MAXN],fa[MAXN];
ll n,A,B,tot,ans;
struct node
{
ll x,y,z;
}a[MAXM];
O3 inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
O3 inline bool cmp(node a,node b)
{
return a.z<b.z;
}
O3 inline ll getfa(ll x)
{
return !fa[x]?x:fa[x]=getfa(fa[x]);
}
O3 int main()
{
freopen("pupil.in","r",stdin);
freopen("pupil.out","w",stdout);
n=read(),A=read(),B=read();
fo(i,1,n)x[i]=read(),y[i]=read();
fo(i,1,n)
{
a[++tot].x=i,a[tot].y=n+1,a[tot].z=A;
fo(j,i+1,n)
{
a[++tot].x=i,a[tot].y=j,a[tot].z=B*(abs(x[i]-x[j])+abs(y[i]-y[j]));
}
}
n=tot,sort(a+1,a+n+1,cmp);
fo(i,1,n)
{
ll x=a[i].x,y=a[i].y,z=a[i].z;
if (getfa(x)!=getfa(y))fa[getfa(x)]=getfa(y),ans+=z;
}
printf("%lld\n",ans);
return 0;
}