村通网 / 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; }
从0到1很难,但从1到100很容易