*(File IO): input:irrigation.in output:irrigation.out
時間限制: 1000 ms 空間限制: 128000 KB 具體限制
題目描述
由於最近缺少降雨,農夫約翰決定在他的N塊農田之間建立一個供水管網。每塊的位置可以用一個二維座標來表示,在第i塊地和第j塊地之間修建一個管道的話,代價是。農夫約翰想要建立一個花費代價最小的供水管網,使得他所有的地都能被連接在一起(使得水能夠通過一系列的管道流到各個田地裏去)。不幸的是,建造管道的人拒絕建造花費代價小於C的單條管道。請幫助約翰計算最少需要花費多少代價,才能建成這個供水管網。
輸入
第一行是兩個正整數和。
第行到第行,每行兩個整數,表示和。
輸出
輸出建立供水管網的最小代價,如果不能建立供水管網,就輸出。
樣例輸入
3 11
0 2
5 0
4 3
樣例輸出
46
數據範圍限制
。
提示
樣例中,約翰不能在和之間建立管道,因爲這個管道的代價是。因此,他只能在和之間修建一條管道,花費是,在和之間修建一條管道,花費是,所以總的最小花費是。
解題思路
這道題就是一道最小生成樹,可以採用普里姆算法.
代碼
#include<bits/stdc++.h>
using namespace std;
int n,c,x[2020],y[2020],a[2020][2020],v[2020],b[2020],minn,k,ans;
int main()
{
freopen("irrigation.in","r",stdin);
freopen("irrigation.out","w",stdout);
scanf("%d%d",&n,&c);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
a[i][j]=999999999;
for(int i=1; i<=n; i++)
{
scanf("%d%d",&x[i],&y[i]);
for(int j=1; j<=i-1; j++)
if((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])>=c)
a[i][j]=a[j][i]=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
v[1]=1;
for(int i=2; i<=n; i++)
b[i]=a[1][i];
for(int j=1; j<=n-1; j++)
{
minn=999999998;
for(int j=1; j<=n; j++)
if(v[j]==0&&b[j]<=minn)
{
minn=b[j];
k=j;
}
v[k]=1;
ans+=b[k];
for(int j=1; j<=n; j++)
if(v[j]==0&&a[j][k]<=b[j])
b[j]=a[j][k];
}
for(int i=1; i<=n; i++)
if(!v[i])
{
printf("-1");
return 0;
}
printf("%d",ans);
}