村通网 / pupil

【题目描述】

为了加快社会主义现代化,建设新农村,农夫约(FarmerJo)决定给农庄里每座建筑都连上互联网,方便未来随时随地网购农药。

他的农庄很大,有N座建筑,但地理位置偏僻,网络信号很差。

一座建筑有网,当且仅当满足以下至少一个条件:

1、    给中国移动交宽带费,直接连网,花费为A。

2、    向另外一座有网的建筑,安装共享网线,花费为B×两者曼哈顿距离。

现在,农夫约已经统计出了所有建筑的坐标。他想知道最少要多少费

用才能达到目的。

【输入格式】第一行:三个正整数,代表N、A、B。

接下来N行:每行两个整数Xi、Yi,第i行代表第i座建筑的坐标。

【输出格式】第一行:一个整数,代表答案。

【样例】

IN

3 36 3
-9 -6
-5 -7
3 0

OUT

87

【数据范围】

30%的数据:N <= 3,A <= 50,B <= 5

60%的数据:N <= 100,A <= 1000,B <= 20

100%的数据:N <= 103,A <= 104,B <= 50,|Xi|,|Yi| < 215


 永远认不出来最小生成树的题

 

code

#include<stdio.h>
#include<algorithm>
using namespace std;
const int MX=1000001;
struct Edge {
    int u,v;
    long long val; 
}edge[MX];
int tot,n,a,b,ans;
int fa[MX],x[MX],y[MX];

int get(int k) {
    if(fa[k]==k) return k;
    return fa[k]=get(fa[k]);
}

void merge(int par,int kid) {
    fa[get(kid)]=get(par);
}

/*bool operator<(const Edge &q,const Edge &p){
    return q.val<p.val;
}*/

bool cmp (Edge p,Edge q) {
    return p.val<q.val;
}

int main()
{
/*    freopen("pupil.in","r",stdin);
    freopen("pupil.out","w",stdout);
*/    scanf("%d%d%d",&n,&a,&b);
    for(int i=1;i<=n;++i) {
        scanf("%d%d",&x[i],&y[i]); 
    }
    for(int i=1;i<=n;++i) {
        for(int j=i+1;j<=n;++j) 
        {
            long long pri=(abs(x[i]-x[j])+abs(y[i]-y[j]))*b;
            edge[++tot]=(Edge){i,j,pri};
        }
    }
    for(int i=1;i<=n;++i) edge[++tot]=(Edge){i,n+1,a};
    sort(edge+1,edge+1+tot,cmp);
    for(int i=1;i<=n;++i) fa[i]=i;
    for(int i=1;i<=tot;i++)
    {
        if (get(edge[i].u)!=get(edge[i].v))
        {
            ans+=edge[i].val;
            fa[get(edge[i].u)]=get(edge[i].v);
        }
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2018-10-14 17:27  qseer  阅读(177)  评论(0编辑  收藏  举报