P2872 [USACO07DEC]道路建设Building Roads

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxx=1000001;// 最小生成树的这个东西一定不要开小了...
int tot=1,x[maxx],y[maxx];
double ans=0;//注意double
struct data
{
    int x,y;
    double dis;
}a[maxx];//插歪坐标和路径长
int f[maxx];
int getf(int x)//找爸爸(
{
    if(f[x]==x) return x;
    else f[x]=getf(f[x]);
    return f[x];
}
double dit(int x1,int x2,int y1,int y2)//注意double
{
    return sqrt(double(pow(x1-x2,2))+double(pow(y1-y2,2)));
}
bool cmp(data a,data b)//比较路径长
{
    return a.dis<b.dis;
}
void merge(int x, int y) //合并
{
    x=getf(x);
    y=getf(y);
    if(x!=y) f[y]=x;
}
int main()
{
    int n,m,i,j;
    cin>>n>>m;
    for(i=1;i<=n;i++)//茶几初始化
    {
        f[i]=i;
    }
    for(i=1;i<=n;i++)//普通输入
    {
        cin>>x[i]>>y[i];
    }
    for(i=1;i<=n;i++)
    {
        for(j=i+1;j<=n;j++)
        {
            a[tot].x=i;
            a[tot].y=j;
            a[tot].dis=dit(x[i],x[j],y[i],y[j]);
            tot++;
        }
    }
    for(i=1;i<=m;i++)//已联通输入
    {
        int t,tt;
        cin>>t>>tt;
        a[++tot].x=t;
        a[tot].y=tt;
        a[tot].dis=0;
    }
    sort(a+1,a+1+tot,cmp);//排序
    int k=0;
    for(i=1;i<=tot;i++) //kruskal
    {
        if(getf(a[++k].x)!=getf(a[k].y)) 
        {
            ans+=a[k].dis;
            merge(a[k].x,a[k].y);
        }
    }
    printf("%.2lf",ans);//保留两位
    return 0;
}

RE真好玩

猜你喜欢

转载自www.cnblogs.com/LSWorld/p/9704026.html