CF437div D 贪心+并查集

本文介绍了一种解决特定图论问题的方法,该问题是找到所有节点间路径的最大最小权值,并计算其平均值。通过将边按权值排序,并使用并查集进行优化,实现了高效的求解。

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

题意:给出一个联通图 然后每一个节点有一个权值,然后我们需要做的是 是对于没两个点之间之间的所有简单路径而言 定义简单路径上面的点的最小值为这条简单路径的代价 而这些最小值中的最大值就是我们要求的这两点之间的函数值  最后我们需要给所有两点之间 函数值的均值

解法:这题和上两天网赛上的一题非常相似啊  但是又是那一题的加强版 首先点和边都是10w数量级的 也就是说我们是不能用dfs等的方法 然后考虑到正难则反 寻找点就是先建图 然后进行寻找一些点之间的权值 首先是要最小值 那么我们将所有的边按照从达到小排序 这样一来我们进行加点的时候更新出的值就一定是路径上的最小值了 然后考虑到要使所有的路径中的最大值 其实在路径合并的过程中也已经满足 那么我们只需要利用并查集构图就可以了

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 111111
int x,y,n,m,fa[maxn],sz[maxn];
double val[maxn];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
struct edge{
    int l,r;double w;
    bool operator<(const edge&x)const{
        return w>x.w;
    }
}e[maxn];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%lf",&val[i]);fa[i]=i;sz[i]=1;
    }
    for(int i=0;i<m;++i){
        scanf("%d%d",&x,&y);
        e[i].l=x,e[i].r=y;
        e[i].w=min(val[x],val[y]);
    }
    sort(e,e+m);
    double s=0.0;
    for(int i=0;i<m;++i){
        x=find(e[i].l);y=find(e[i].r);
        if(x!=y){
            s+=e[i].w*sz[x]*sz[y];
            sz[x]+=sz[y];fa[y]=x;
        }
    }
    printf("%f\n",s*2/n/(n-1));
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值