迷之节约

迷之节约
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;
}

你可能感兴趣的:(迷之节约)