【雅礼联考GDOI2017模拟9.2】Zjr506的捕猫计划

Description

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

Solution

一开始把模型看成,找到所有的简单环,然后再逐个合并。
但是,找简单环再合并,太麻烦了!!!
其实有很多个环,然后每个环再去掉一条边,使得去掉的边的最小。那么明显可以用最大生成树。
然后,就没了。

Code

#include<iostream> 
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define rep(i,a) for(i=first[a];i;i=next[i])
using namespace std;
const int maxn=100007;
int i,j,k,l,t,n,m;
double ans,ans1;
struct node{
    int a,b;
    double c;
}a[maxn];
int x[maxn],y[maxn],f[maxn];
bool bz[maxn],az[maxn];
int gf(int x){
    if(!f[x])return x;
    f[x]=gf(f[x]);
    return f[x];
}
double ju(int x,int y,int xx,int yy){
    return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));
}
bool cmp(node x,node y){
    return x.c>y.c;
}
int main(){
    scanf("%d%d",&n,&m);
    fo(i,1,n)scanf("%d%d",&x[i],&y[i]);
    fo(i,1,m){
        scanf("%d%d",&a[i].a,&a[i].b);
        a[i].c=ju(x[a[i].a],y[a[i].a],x[a[i].b],y[a[i].b]);
        ans+=a[i].c;
    }
    sort(a+1,a+1+m,cmp);
    fo(i,1,m){
        int u=gf(a[i].a),v=gf(a[i].b);
        if(u!=v){
            ans1+=a[i].c; 
            f[v]=u;   
        }
    }
    ans=ans-ans1;
    printf("%.4lf\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值