首页 > 其他分享 >[ABC259F] Select Edges 题解

[ABC259F] Select Edges 题解

时间:2024-04-02 21:22:24浏览次数:13  
标签:nxt int 题解 ll dfs ABC259F Edges mx dp

很容易想到树形 dp。

考虑在有根树内,每个点都有两种状态:

  1. 不选自己和父亲的边;
  2. 要选自己和父亲的边。

那么单独对于子树内部而言,就要分两种情况:

  1. 最多可以向 \(d_i\) 个孩子连边,对应上述第一种情况,我们称之为 \(f_i\);
  2. 最多可以向 \(d_i-1\) 个孩子连边,对应上述第二种情况,我们称之为 \(dp_i\)。

最基本的状态是不选自己和子树的连边,答案即为 \(\sum\limits_{j\in ison} f_j\)。

然后发现每次连 \((i,j)\) 这条边,答案会加上 \(mx_j=dp_j+w_{(i,j)}-f_j\)。

那么对于 \(f_i\),就可以挑选前 \(d_i\) 大的 \(mx_j\),答案加上所有 \(>0\) 的 \(mx\) 值。\(dp_i\) 同理。

时间复杂度 \(O(n\log n)\)。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e5+5;
int n,k,u[N],v[N],d[N],r[N];
int m,h[N],to[N*2],nxt[N*2];
ll w[N*2],mx[N],f[N],dp[N];
int cmp(ll x,ll y){return x>y;}
void add(int x,int y,ll z){
    to[++m]=y;
    w[m]=z;
    nxt[m]=h[x];
    h[x]=m;
}void dfs(int x,int fa){
    for(int i=h[x];i;i=nxt[i]){
        int y=to[i];
        if(y==fa) continue;
        dfs(y,x);
        dp[x]+=f[y];
    }int k=0;
    for(int i=h[x];i;i=nxt[i])
        if(to[i]!=fa)
            mx[++k]=dp[to[i]]+w[i]-f[to[i]];
    sort(mx+1,mx+k+1,cmp);
    for(int i=1;i<d[x];i++){
        if(mx[i]<=0) break;
        dp[x]+=mx[i];
    }f[x]=dp[x];
    if(mx[d[x]]>0) f[x]+=mx[d[x]];
    if(!d[x]) dp[x]=-1e9;
    for(int i=1;i<=k;i++) mx[i]=0;
}int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>d[i];
    for(int i=1;i<n;i++){
        int x,y,z;
        cin>>x>>y>>z;
        add(x,y,z);
        add(y,x,z);
    }dfs(1,0);
    cout<<f[1];
    return 0;
}

标签:nxt,int,题解,ll,dfs,ABC259F,Edges,mx,dp
From: https://www.cnblogs.com/chang-an-22-lyh/p/18111530

相关文章

  • ABC347G 题题解
    还算是比较经典了。首先我们注意到一个性质:\(1+3+\cdots+n=n^2\)。所以我们可以把平方拆开。然后容易证明\(a_{i,j}\)填\(1\)一定比填\(0\)不劣。我们可以把\(a_{i,j}\)拆成\(4\)个点,然后我们想到了最小割。构造网络:\(a_{i,j,x}\leftarrowa_{i,......
  • 三道dp的题解报告
    三道dp的题解报告圆题目来源牛客练习赛122D题练习赛链接https://ac.nowcoder.com/acm/contest/75768题面原题面为中文就直接放原题面截图了。解法事实上,把\(n\)与\(1\)断掉,断环为链,把原来的线段看成区间,线段相交就是区间之间部分覆盖(区间有重复部分但是没有相互包含关......
  • 题解:AT_abc176_e [ABC176E] Bomber
    分析我们可以用\(hf\)和\(wf\)分别储存每行的目标数及每列的目标数。然后我们可以贪心:若想摧毁最多的目标,则选定的位置所在的行是所有行中目标最多的,所在的列是所有列中目标最多的(感性理解一下)。但是,选定的位置也可能有一个目标。在统计摧毁的目标数时,该目标被算了两次......
  • P2143 [JSOI2010] 巨额奖金 题解
    P2143[JSOI2010]巨额奖金题解矩阵树定理+Kruskal最小生成树计数。思路MST都是喵喵题。引理1:所有合法的权值相同边的连边方案,得到的连通块情况是相同的。感性理解:如果不相同意味着至少有一条边可以连通一对连通块。所以我们可以这么做:先跑Kruskal标记树边,然后枚举......
  • P1967 [NOIP2013 提高组] 货车运输 题解
    P1967[NOIP2013提高组]货车运输原题地址思路:由于题目要求的是使两点之间的最小边权最大,所以可以构造最大生成树(最大生成树一定是最大瓶颈生成树,而瓶颈生成树上两点之间的路径,在原图中的所有路径中,最小边权仍然最大,即满足题目要求,详见https://oi-wiki.org/graph/mst/#性质),......
  • Golang | Leetcode Golang题解之第4题寻找两个正序数组的中位数
    题目:题解:funcfindMedianSortedArrays(nums1[]int,nums2[]int)float64{iflen(nums1)>len(nums2){returnfindMedianSortedArrays(nums2,nums1)}m,n:=len(nums1),len(nums2)left,right:=0,mmedian1,median2:=0,0......
  • CF1935D Exam in MAC 题解
    ExaminMAC题意\(t\)组数据。给定一个大小为\(n\)的集合\(s\)和一个整数\(c\),保证\(0\leqslants_i\leqslantc(1\leqslanti\leqslantn)\)。求有多少对整数数对\((x,y)\),满足:\(0\leqslantx\leqslanty\leqslantc\)。\(x+y\notins\)且\(y-x\not......
  • 2024最新一线互联网大厂常见高并发面试题解析
    面试官:临界区是什么?答:临界区用来表示一种公共资源或者说是共享资源,可以被多个线程使用。但是每一次,只能有一个线程使用它,一旦临界区资源被占用,其他线程要想使用这个资源,就必须等待。比如,在一个办公室里有一台打印机,打印机一次只能执行一个任务。如果小王和小明同时需要打......
  • 【赛题解析】【移动应用开发】全国职业院校技能大赛任务一:实现社区首页功能解析
    ​培训、环境、资料、考证公众号:波比网络公众号2:波比网络工作室移动应用开发技能大赛交流群:548238632波比网络专注于技能提升,赋能**本文章全文由波比网络原创,非法转载必究!**文章目录移动应用与开发任务1:实现社区首页功能1.界面顶部显示所在社区名称、轮播图和社......
  • IDEA中新建SpringBoot模块,JDK版本问题解决
    问题描述IDEA中新建SpringBoot模块,使用的JAVAJDK1.8,新建模块时选项中没有JDK8: 运行时报错,JDK之类的问题解决方案,查看修改以下四个地方:(1)设置-Java编译器 (2)项目结构--依赖以及源码 ......