迷之节约 分类: sdutOJ 最小生成树 2015-06-24 19:10 10人阅读 评论(0) 收藏
迷之节约
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
FF超级有钱,最近又买了n个(1 <= n <= 300)小岛,为了能在岛之间游玩,FF决定要在岛之间修桥以保证任意两岛之间都要可达。但是FF又超级抠门,想让造桥费用最小。现在由于技术原因,一座桥的造价为两桥之间直线距离的平方。现在给你桥的坐标,让你求最小造价是多少。
输入
多组输入。
对于每组数据,第一行输入n,接下来的n行,每行两个整数x,y(-1000 <= x,y <= 1000)代表桥的坐标。
输出
对于每组数据输出一个整数代表最小花费。
示例输入
2
1 1
1 2
示例输出
1
最小生成树
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define RR freopen("input.txt","r",stdin)
#define WW freopen("ouput.txt","w",stdout)
using namespace std;
const int INF=0x3f3f3f3f;
int n;
int DIS(int x,int y,int a,int b)
{
return (x-a)*(x-a)+(y-b)*(y-b);
}
struct Point
{
int x[400];
int y[400];
int Dis[400][400];
bool vis[400];
int Dist[400];
long long sum;
void Input()
{
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;j<=n;j++)
{
Dis[i][j]=Dis[j][i]=DIS(x[i],y[i],x[j],y[j]);
}
}
}
void Prime()
{
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++)
{
Dist[i]=Dis[1][i];
}
vis[1]=true;
sum=0;
for(int i=1;i<n;i++)
{
int Min=INF;
int flag;
for(int j=1;j<=n;j++)
{
if(Min>Dist[j]&&!vis[j])
{
Min=Dist[j];
flag=j;
}
}
vis[flag]=true;
sum+=Min;
for(int j=1;j<=n;j++)
{
if(Dist[j]>Dis[flag][j]&&!vis[j])
{
Dist[j]=Dis[flag][j];
}
}
}
}
void Output()
{
printf("%lld\n",sum);
}
}FF;
int main()
{
while(~scanf("%d",&n))
{
FF.Input();
FF.Prime();
FF.Output();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。