ABC394F题解

今天我们来讲‌Anti bribe & corruption 394 AtCoder Beginner Contest 394_F。这道题把我干成沙子了。

原题

题目描述

给定一棵包含 N N N 个顶点的无向树 T T T。顶点编号为 1 , 2 , ... , N 1, 2, \ldots, N 1,2,...,N,第 i i i 条边连接顶点 A i A_i Ai 和顶点 B i B_i Bi。

定义满足以下两个条件的图为烷烃

  • 该图是一棵无向树
  • 所有顶点的度数为 1 1 1 或 4 4 4,且至少存在一个度数为 4 4 4 的顶点

请判断 T T T 中是否存在满足烷烃定义的子图。若存在,求此类子图的顶点数的最大值;否则输出 − 1 -1 −1。

输入格式

输入通过标准输入按以下格式给出:

N N N
A 1 A_1 A1 B 1 B_1 B1
A 2 A_2 A2 B 2 B_2 B2
⋮ \vdots ⋮
A N − 1 A_{N-1} AN−1 B N − 1 B_{N-1} BN−1

输出格式

若存在满足烷烃定义的子图,输出其顶点数的最大值;否则输出 − 1 -1 −1。

输入输出样例 #1

输入 #1

复制代码
9
1 2
2 3
3 4
4 5
2 6
2 7
3 8
3 9

输出 #1

复制代码
8

输入输出样例 #2

输入 #2

复制代码
7
1 2
1 3
2 4
2 5
3 6
3 7

输出 #2

复制代码
-1

输入输出样例 #3

输入 #3

复制代码
15
8 5
2 9
1 12
6 11
9 3
15 1
7 12
7 13
10 5
6 9
5 1
1 9
4 5
6 14

输出 #3

复制代码
11

说明/提示

约束条件

  • 1 ≤ N ≤ 2 × 1 0 5 1 \leq N \leq 2 \times 10^5 1≤N≤2×105
  • 1 ≤ A i , B i ≤ N 1 \leq A_i, B_i \leq N 1≤Ai,Bi≤N
  • 输入的图是一棵无向树
  • 所有输入值为整数

样例解释 1

选取顶点 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 1, 2, 3, 4, 6, 7, 8, 9 1,2,3,4,6,7,8,9 及边 ( 1 , 2 ) (1,2) (1,2)、 ( 2 , 3 ) (2,3) (2,3)、 ( 3 , 4 ) (3,4) (3,4)、 ( 2 , 6 ) (2,6) (2,6)、 ( 2 , 7 ) (2,7) (2,7)、 ( 3 , 8 ) (3,8) (3,8)、 ( 3 , 9 ) (3,9) (3,9) 构成的子图满足烷烃条件。其中顶点 2 2 2 和顶点 3 3 3 的度数为 4 4 4,其余顶点度数为 1 1 1,因此顶点数的最大值为 8 8 8。

翻译由 DeepSeek R1 完成

思路

这道题是一个树形 D P DP DP。

状态

d p u , i dp_{u,i} dpu,i 为以 u u u 为根节点,有 i i i 个子节点,最大节点个数。因为最多只能有四个,所以不会炸。

初始化

d p u , 0 dp_{u,0} dpu,0 是 1 1 1 就是它本身。其它的就为无穷小。

转移方程

d p u , i = m a x ( d p u , i , d p u , i − 1 + m a x ( d p v , 0 , d p v , 3 ) ) dp_{u,i}=max(dp_{u,i},dp_{u,i-1}+max(dp_{v,0},dp_{v,3})) dpu,i=max(dpu,i,dpu,i−1+max(dpv,0,dpv,3))。

也就是说它可以选择加这个儿子或不加。要加的话就必须从儿子有三个或零个子节点中选,不然就不满足要求。由此可以推出此方程

Code

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,h[414514],e[414514],ne[414514],idx,dp[414514][5],mx=-1;
void add(int u,int v){
	e[idx]=v,ne[idx]=h[u],h[u]=idx++;
} 
void dfs(int u,int pre){
	dp[u][1]=-0x3f3f3f3f,dp[u][2]=-0x3f3f3f3f,dp[u][3]=-0x3f3f3f3f,dp[u][4]=-0x3f3f3f3f;
	dp[u][0]=1;
	for(int i=h[u];~i;i=ne[i]){
		int j=e[i];
		if(j==pre){
			continue;
		}
		dfs(j,u);
		for(int i=4;i>=1;i--){
			dp[u][i]=max(dp[u][i],dp[u][i-1]+max(dp[j][0],dp[j][3]));
		}
	}
	if(dp[u][1]>2){
		mx=max(mx,dp[u][1]);
	} 
	mx=max(mx,dp[u][4]);
}
int main(){
	memset(h,-1,sizeof(h));
	cin>>n;
	for(int i=1;i<=n-1;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	dfs(1,0);
	cout<<mx;
	return 0;
}
相关推荐
ChoSeitaku13 小时前
NO.91十六届蓝桥杯备战|图论基础-图的存储和遍历|邻接矩阵|vector|链式前向星(C++)
c++·蓝桥杯·图论
袖清暮雨13 小时前
【专题】图论
算法·图论
课堂剪切板14 小时前
ch07 部分题目思路
图论
壮Sir不壮17 小时前
图论之并查集——含例题
开发语言·golang·图论
辰阳星宇17 小时前
213、【图论】有向图的完全联通(Python)
开发语言·python·图论
Kita~Ikuyo20 小时前
基础数学:图论与信息论
python·算法·llm·图论
南星啊1 天前
【模板】缩点
算法·图论
smile-yan1 天前
拓扑排序 —— 2. 力扣刷题207. 课程表
数据结构·算法·图论·拓扑排序
nuo5342022 天前
第十六届蓝桥杯 省赛C/C++ 大学B组
c语言·c++·算法·蓝桥杯·图论
踏雪亦无痕2 天前
论文笔记:Dynamic Spectral Graph Anomaly Detection
论文阅读·深度学习·图论·异常检测