T78748 【lcez模拟赛】机场Ⅰ

T78748 【lcez模拟赛】机场Ⅰ

其实这就是最小生成树的题辣

注意输入毒瘤

输入的话要避免记录中间这个‘ , ’

如下操作可以解决

特别注意%d之间的‘ , ’

边的权值要现算

存点的话存横纵坐标

注意本题是进行好多次询问,模块化一下吧

放代码

#include<bits/stdc++.h>

using namespace std;

int T,n,m,fa[1001];

int find(int x)
{
    if(fa[x]!=x) fa[x]=find(fa[x]);
    return fa[x];
}

struct egg
{
    int x,y;
}point[1001];

struct edge
{
    int from,to;
    double dis;
}Edge[20001];

bool cmp(edge a,edge b)
{
    return  a.dis <b.dis;
}

double dis(egg a,egg b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}


void klske()
{
    int flag=0;
    int k=0;
    double ans=0;
    
    for(int i=1;i<=n;i++)  fa[i]=i;
    
    sort(Edge+1,Edge+m+1,cmp);
    
    for(int i=1;i<=m&&k<=n-1;i++)
    {
        int f1=find(Edge[i].from) ;
        int f2=find(Edge[i].to) ;
        if(f1!=f2)
        {
            ans+=Edge[i].dis;
            fa[f1]=f2;
            k++;
        }
        
        if(k==n-1)
        {
            flag=1;
            printf("%.4lf
",ans);
            break;
        }
        
    }
    
    if(!flag)
    printf("orz
");
    
    
}

void caozuo()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
      scanf("%d,%d",&point[i].x ,&point[i].y );
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&Edge[i].from ,&Edge[i].to );
        Edge[i].dis=dis(point[Edge[i].from] ,point[Edge[i].to]);
    }
    
    klske();
    
}

int main()
{
    scanf("%d",&T);
    for(int i=1;i<=T;i++)
      caozuo();
}
原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/10853708.html