POJ 2349 Arctic Network(最小生成树 kruscal or prim)

本文通过Kruskal算法解决了一个复杂的最小生成树问题。主要讲述了如何将坐标转换为边的信息,并通过Kruskal算法求得最小生成树中除去卫星数量减一的最大边的剩余最小生成树中的最大边。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PS:博主这个题比较闹心。首先是理解题意就花了好长时间。T^T。写好后没有使用强制类型转换CE好久,之后又是顶点数量确定后没有确定边的最大数量,连续RE十几次,检查就花了几个小时,只能凌晨发文了。。。。。。
来,此题描述不好理解。。(或许是博主英语拙计的缘故吧T^T)。。题目要求最小生成树中除去卫星数量减一的最大边的剩余最小生成树中的最大边。说起来好绕口 =.= 。好吧,prim kruscal 都可以。博主用的是kruscal。
还有注意的就是点的坐标转换为边的信息时的代码。

#include <stdio.h>

#include <math.h>

#include <algorithm>

const int MAXCOST = 250010;   //边的最大数目。

using namespace std;

typedef struct   //储存坐标
{
    int x,y;
}node;

node point[MAXCOST];

int cnt;

typedef struct  //储存边的信息
{
    int u,v;
    double w;
}Edge;

Edge  edge[MAXCOST];

bool cmp( const Edge a ,const Edge b)
{
    return a.w<b.w;
}

int root[MAXCOST];

int main()
{
    void len(int x,int y);
    void init(int m);
    int find_set(int x);
    void union_set(int x,int y);
    void kruscal(int n,int m);
    int k,n,m;
    double x,y;
    scanf("%d",&k);
    while(k--)
    {
        cnt = 0;
        scanf("%d %d",&n,&m);
        for(int i = 0 ; i < m ; i++)
        {
            scanf("%d %d",&point[i].x,&point[i].y); //输入坐标的信息
        }
        for(int i = 0 ; i < m ; i++)     //计算任意两点间的距离。
        {
            for(int j = 0 ; j < m ; j++)
            {
                if(i!=j) //kruscal算法不用存回路的边的信息
                    len(i,j);
            }
        }
        kruscal(n,m);
    }
    return 0;
}

void init(int m)
{
    for(int i = 0 ; i < m ; i++)
    {
        root[i] = i;
    }
}

int find_set(int x)
{
    if(x!=root[x])
    {
        root[x] = find_set(root[x]);
    }
    return root[x];
}

void union_set(int x,int y)
{
    int a = find_set(x);
    int b = find_set(y);
    if(a!=b)
    {
        root[b] = a;
    }
}

void len(int x,int y)  //计算两点间的距离。PS:注意强制类型转化
{
    edge[cnt].v = x;
    edge[cnt].u = y;
    edge[cnt++].w = sqrt(double((point[x].x-point[y].x) * (point[x].x-point[y].x)+(point[x].y - point[y].y) * (point[x].y - point[y].y)));
}

void kruscal(int n,int m)
{
    int key = 0;
    double distance;
    sort(edge,edge+cnt,cmp);
    init(m);
    for(int i = 0 ; i < cnt ; i++)
    {
        if(find_set(edge[i].u) != find_set(edge[i].v))
        {
            key++;
            union_set(edge[i].u,edge[i].v);
            distance = edge[i].w;
           if(key == m-n)  //找到最小生成树中除去s-1条最大边的最大边长
            {
                printf("%.2lf\n",distance);

            }
        }
    }
}


ps:时间好晚。。。碎个好觉去。。明天还要上课T*T

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值