【JZOJ5353】村通网

34 篇文章 0 订阅
19 篇文章 0 订阅

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值