Zjr506的捕猫计划

本文介绍了一道关于最小藩篱拆除的问题,通过构建图模型,采用最大生成树算法解决如何以最小总长度拆除藩篱,使得所有节点形成一棵树,进而实现让所有“猫”逃脱的目标。

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

题目描述

Zjr506很喜欢猫,某一天他突然心血来潮,想捕捉学校里活动的猫。
为了捕猫,Zjr506在校园中放置了N个木桩,当他见到有猫进入他的狩猎范围后,就会以迅雷不及掩耳的速度在一些木桩之间绕上藩篱以困住这些猫。
一段时间后,Zjr506在绕了M个藩篱后兴高采烈的离开了。作为正义的使者,Ztxz16不忍心看到这些猫受到折磨,于是决定拆除一些藩篱让所有的猫都逃出去。因为Zjr506的巧妙设计,藩篱不会在除木桩之外的地方相交。这些藩篱构成了一些封闭的区域,每一个区域中都有一只猫。
因为Zjr506制造这些藩篱也不容易,所以Ztxz16希望拆除的藩篱总长度尽量小,现在他希望你告诉他最小的总长度。

数据范围

N <= 10000, M <= 50000

题目描述是有问题的,有一种特殊情况即一个藩篱经过不止两个木桩,可以是三个四个,因为题目仅仅说明藩篱不会在除木桩之外的地方相交。除去这种情况,题解的做法就是对的。

那么考虑要拆除一些藩篱,使图中不在任何环,也就是说删完藩篱后的图会成为一棵树,那么我们只要做一遍最大生成树即可。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=10000+5;const int maxm=50000+5;
int i,j,f[maxn],n,m;
double sum;
struct ar{
    int x,y;double d;
}b[maxm],z[maxn];
bool cmp(ar x,ar y){
    return x.d>y.d;
}
double sqr(int x){
    double a=x;
    return a*a;
}
int get(int x){
    if (f[x]==0) return x;
    return f[x]=get(f[x]);
}
int main(){
    scanf("%d%d",&n,&m);
    fo(i,1,n) scanf("%d%d",&z[i].x,&z[i].y);
    fo(i,1,m){
        scanf("%d%d",&b[i].x,&b[i].y);
        int x=b[i].x,y=b[i].y;
        b[i].d=sqr(z[x].x-z[y].x)+sqr(z[x].y-z[y].y);
        b[i].d=sqrt(b[i].d);
        sum+=b[i].d;
    }
    sort(b+1,b+1+m,cmp);
    fo(i,1,m){
        int x=b[i].x,y=b[i].y;
        x=get(x),y=get(y);
        if (x!=y){
            sum-=b[i].d;
            f[x]=y;
        }
    }
    printf("%.5lf\n",sum);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值