[CF444E]DZY Loves Planting

本文介绍了一种解决特定树形结构问题的方法,利用网络流和Hall定理进行优化,通过并查集实现了高效的算法解决方案。

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

题目大意

给定一棵n个点的树,每条边有边权ci
定义g(x,y)表示点x到点y路径上边权的最大值。特殊地g(x,x)=0
对于一个序列{pn}(1pin),定义

f(p)=mini=1ng(i,pi)

现在有n个限制xi,表示i{pn}中的出现的次数不超过xi

1ci104,1xin
原数据范围n3000


题目分析

首先有个很显然的想法:二分答案,然后用网络流来判定答案是否可行。于是乎好像可以过掉原数据???
来考虑更优的做法:可以发现网络流的过程其实就是一个二分图匹配,考虑怎么把这个问题套上Hall定理。
从小到大加边,然后我们可以把联通块缩起来,这个联通块内所有点都要向联通块外的点匹配才能获得当前边权的答案。根据Hall定理其实就是联通块内点数小于等于联通块外所有点x的和才合法。
直接使用并查集搞一搞就可以了。
时间复杂度O(nα(n))


代码实现

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cctype>

using namespace std;

int read()
{
    int x=0,f=1;
    char ch=getchar();
    while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar();
    while (isdigit(ch)) x=x*10+ch-'0',ch=getchar();
    return x*f;
}

const int N=3005;

struct edge
{
    int x,y,len;

    bool operator<(edge const e){return len<e.len;}
}ed[N];

int fa[N],rk[N],a[N],size[N];
int n,ans,err,sum;

int getfather(int son){return fa[son]==son?son:fa[son]=getfather(fa[son]);}

void merge(int x,int y)
{
    x=getfather(x),y=getfather(y);
    if (x==y) return;
    if (rk[x]<rk[y]) swap(x,y);
    fa[y]=x,rk[x]+=rk[x]==rk[y];
    err-=sum-a[x]<size[x],err-=sum-a[y]<size[y];
    size[x]+=size[y],a[x]+=a[y],err+=sum-a[x]<size[x];
}

void calc()
{
    err=0;
    for (int i=1;i<=n;++i) err+=sum-a[i]<(size[i]=1),fa[i]=i,rk[i]=0;
    for (int cur=1;cur<n;)
    {
        if (!err) ans=ed[cur].len;
        for (int ptr=cur;cur<n&&ed[cur].len==ed[ptr].len;++cur) merge(ed[cur].x,ed[cur].y);
    }
}

int main()
{
    freopen("planting.in","r",stdin),freopen("planting.out","w",stdout);
    n=read();
    for (int i=1;i<n;++i) ed[i].x=read(),ed[i].y=read(),ed[i].len=read();
    sort(ed+1,ed+n);
    for (int i=1;i<=n;++i) sum+=a[i]=read();
    calc(),printf("%d\n",ans);
    fclose(stdin),fclose(stdout);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值