现在的位置: 首页 > 综合 > 正文

POJ 3771 World Islands

2014年08月29日 ⁄ 综合 ⁄ 共 1376字 ⁄ 字号 评论关闭

题意:给你n个点(坐标表示),求删除其中一个点的最小生成树中长度最小的那个。

思路:由于n的范围是0~50,因此直接枚举每个点,然后求最小生成树,最后取最小值即可。

 

写的时候由于prime没写好,贡献了4个wrong……orz,真是伤心,看来我的基本功还是练得不够好啊。

 

代码:

 

#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
int n;
double m[55][55];
double len[55];
bool vis[55],flag[55];
double minlen;
const double maxd=999999999;
struct Points
{
    int x,y;
};
Points p[55];
double getLen(int a,int b)
{
    double u=(p[a].x-p[b].x)*(p[a].x-p[b].x);
    double v=(p[a].y-p[b].y)*(p[a].y-p[b].y);
    return sqrt(u+v);
}
void prim()
{
    memset(vis,0,sizeof(vis));
    int z=flag[0]?1:0;
    for(int i=0;i<n;++i)
    {
        if(!flag[i])
        {
            len[i]=m[z][i];
        }
    }
    vis[z]=true;
    double minnum;
    int dir;
    double sum=0;
    for(int i=1;i<n-1;++i)
    {
        minnum=maxd;
        for(int j=0;j<n;++j)
        {
            if(!vis[j]&&!flag[j]&&len[j]<minnum)
            {
                minnum=len[j];
                dir=j;
            }
        }
        sum+=minnum;
        vis[dir]=true;
        for(int k=0;k<n;++k)
        {
            if(!flag[k])
            {
                len[k]=min(len[k],m[dir][k]);
            }
        }
    }
    minlen=min(minlen,sum);
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=0;i<n;++i)
        {
            cin>>p[i].x>>p[i].y;
        }
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<n;++j)
            {
                m[i][j]=m[j][i]=getLen(i,j);
            }
        }
        memset(flag,0,sizeof(flag));
        minlen=maxd;
        flag[0]=true;
        prim();
        for(int i=1;i<n;++i)
        {
            flag[i-1]=false;
            flag[i]=true;
            prim();
        }
        printf("%.2lf\n",minlen);
    }
    return 0;
}

抱歉!评论已关闭.