畅通工程再续hdu1875

只需prim板子
数据先处理一下,用邻接矩阵好写写过一个Kruskal的但是t了不知道为什么。。。
其实prim跟dij真的没啥差别

#include<iostream>
#include<string.h>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<algorithm>
using namespace std;
int inf=0x3f3f3f3f;
const int maxn=105;
int c;
double mp[maxn][maxn];
double dis[maxn],vis[maxn];
struct P
{
    int x,y;
}point[maxn];
double cal(const P a,const P c)
{
    double zyx=sqrt(pow(c.x-a.x,2)+pow(c.y-a.y,2));
    if(zyx<10||zyx>1000)return inf;
    else return zyx;
}
double prim()
{
    for(int i=1;i<=c;i++)
    {dis[i]=mp[1][i];
    vis[i]=0;}
    dis[1]=0;
    vis[1]=1;
    double ans=0;
    while(1)
    {
        double minn=inf;
        int k;
        for(int i=1;i<=c;i++)
        {if(dis[i]<minn&&!vis[i])
         {minn=dis[i];k=i;}}
         if(minn==inf)break;
        vis[k]=1;
        ans+=dis[k];
        for(int i=1;i<=c;i++)
        {
            dis[i]=min(dis[i],mp[k][i]);
        }
    }
    return ans;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>c;
        memset(mp,0x3f,sizeof(mp));
        for(int i=1;i<=c;i++)
            scanf("%d%d",&point[i].x,&point[i].y);
        for(int i=1;i<=c;i++)
            for(int j=i+1;j<=c;j++)
                mp[i][j]=mp[j][i]=cal(point[i],point[j]);
        int flag=1;double lay=prim();
        for(int i=1;i<=c;i++)
            if(vis[i]==0)flag=0;
        if(flag)cout<<setiosflags(ios::fixed)<<setprecision(1)<<lay*100<<endl;
        else cout<<"oh!"<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43331783/article/details/87973018