首页 > 其他分享 >CodeForces - 1984E

CodeForces - 1984E

时间:2024-07-11 10:18:45浏览次数:14  
标签:par 联通 int max CodeForces 1984E 为根 dp

题目大意

每次在每个联通块中选一个点 \(u\),删除这个点使得联通块分成若干个联通块,再从联通块中选点 \(v\),在新树上连接 \(u,v\),求新树叶节点的最大个数。

分析

易转化为求原树的最大独立集,设 \(f_{u,0/1}\) 为以 1 为根时不选/选 \(u\) 的最大独立集。显然有:

\[dp_{u,0}=\sum\limits_vmax(dp_{v,0/1})\\ dp_{u,1}=\sum\limits_vdp_{v,0}+1 \]

手模第一个样例发现如果以原树的叶子为根节点时,可以同时选择相邻的点,要求以各节点为根的最大独立集,考虑换根 dp,设 \(g_{u,0/1}\) 为以 \(u\) 为根,不选/选 \(u\) 的最大独立集。显然有

\[g_{u,0}=max(g_{fa_u,1},f_{u,0}+g_{fa_u,0}-max(f_{u,0},f_{u,1})\\ g_{u,1}=f_{u,1}+g_{fa_u,0}-max(f_{u,0},f_{u,1})\]

代码

void dfs(int u,int par){
	f[u][0]=0,f[u][1]=1;
	for(int v:G[u]){
		if(v==par) continue;
		dfs(v,u);
		f[u][0]+=max(f[v][1],f[v][0]);
		f[u][1]+=f[v][0];
	}
}

void DFS(int u,int par){
	ans=max(ans,max(g[u][1],g[u][0]+(G[u].size()==1)));
	for(int v:G[u]){
		if(v==par) 
			continue;
		g[v][0]=max(g[u][1],f[v][0]+(g[u][0]-max(f[v][0],f[v][1])));
		g[v][1]=f[v][1]+(g[u][0]-max(f[v][0],f[v][1]));
		DFS(v,u);
	}
}

void Main(){
	n=rd;
	for(int i=1;i<n;i++){
		int u=rd,v=rd;
		G[u].pb(v),G[v].pb(u);
	}
	dfs(1,0);
	g[1][0]=f[1][0],g[1][1]=f[1][1];
	DFS(1,0);
	cout<<ans<<endl;
	ans=0;
	for(int i=1;i<=n;i++) G[i].clear();
}

标签:par,联通,int,max,CodeForces,1984E,为根,dp
From: https://www.cnblogs.com/smilemask/p/18295509

相关文章

  • 高考后第一次Codeforces Round 952 (Div. 4)
    ACreatingWords思路:拿一个容器交换两数值即可#include<bits/stdc++.h>usingnamespacestd;constintN=100001;chara[N],b[N];intmain(){intn;scanf("%d",&n);while(n--){scanf("%s%s",a,b);charjia......
  • Codeforces Round 954(Div. 3)
    CodeforcesRound954(Div.3)目录CodeforcesRound954(Div.3)\(C\).UpdateQueries\(D\).MathematicalProblem\(E\).BeautifulArray方法一:贪心+滑动窗口方法二:DP\(C\).UpdateQueries对索引数组\(ind\)去重排序对字符串\(c\)排序顺序遍历索引数组,将\(s[ind[i]......
  • Codeforces Round 916 (Div. 3)
    A.ProblemsolvingLog签到题,对于给出的字符串,记录每个字母出现的次数,然后遍历一遍,如果对应的字母出现的次数大于它的位次,则说明该题被解出来了,最后输出解题数量即可点击查看代码#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<vector>#......
  • Codeforces Round 956 (Div. 2) 部分题解A~C
    A.ArrayDivisibility题目大意构造长度为n的数组,满足:所有j的aj之和可以被k整除,其中j是k的倍数,k的取值为1~n。思路构造序列1->n即可满足条件。代码实现voidsolve(){  lln;cin>>n;  for(inti=1;i<=n;i++)cout<<i<<"";  cout<<"\n"......
  • Codeforces Round #956 (Div. 2) and ByteRace 2024
    Preface连着好几天因为熬夜看LOL比赛导致白天精神萎靡,都没精力VP了而且明天就要开始统一训练了,趁着最后一天补一下前两天因为看比赛没打的这场吧这场只能说是战术正确,想了会E没啥思路就马上转头去把F写了,后面回头慢慢想E也想出来了,最后极限2h14min出了EA.ArrayDivisibility......
  • codeforces 955 div 2 D
    题目链接D.Beautyofthemountains题目大意解题思路首先记录所有雪山和没有雪山两种山峰的高度差为\(tot\),然后对于每个可能的子矩,我们可以每次给所有山峰都加一或者减一,因此只要计算出矩阵内两种山峰的个数差的绝对值我们就能得到每次操作该子矩阵对tot的贡献\(z_{i}......
  • Codeforces Round956(div2) A~C
    A.ArrayDivisibility题意:对于所有k=1~n,能被j=1~n整除,要求以这些j作为下标a[j]的和也能够被k整除思路:题目有点绕,但是仔细读懂题目其实会发现,其实就是从1到n按顺序输出一遍...,别被样例忽悠了voidsolve(){ intn; cin>>n; for(inti=1;i<=n;i++){ cout......
  • Codeforces Round 953(Div.2) 题解(A-E)
    CodeforcesRound953(Div.2)题解(A-E)A题意Alice有n本书,第一本书有\(a_1\)页,序号为1,第二本书有\(a_2\)页,序号为2,……,第n本书有\(a_n\)页,序号为n。Alice将把所有书分成两堆,并阅读每一堆中序号最大的一本书。Alice喜欢读书,请你告诉她,她最多可以读多少页的书。Solution第......
  • CodeForces CF1980C Sofia and the Lost Operations 题解 但是最后TLE 仅供思路参考
    CodeForcesCF1980CSofiaandtheLostOperations题解嗨嗨,又来了啊,蒟蒻再来一篇题解SofiaandtheLostOperations题面翻译索菲亚有一个包含$n$个整数的数组$a[1],a[2],…,a[n]$。有一天她对这个数组感到厌倦,于是决定顺序地对其应用$m$个修改操作。每个修改操作由一......
  • Codeforces Round #956 (Div. 2) C. Have Your Cake and Eat It Too
    CodeforcesRound#956(Div.2)C.HaveYourCakeandEatItToo题目大意:有长度为nnn的数组a......