首页 > 其他分享 >P8595 「KDOI-02」一个网的路

P8595 「KDOI-02」一个网的路

时间:2024-04-20 11:58:00浏览次数:26  
标签:02 int P8595 KDOI sec dt mx define

P8595 「KDOI-02」一个网的路

树形 dp

显然我们贪心的先执行第一种操作,最后再连边。

森林中不同棵树互不影响,所以考虑最小化每棵树的操作次数。考虑 dp。

我们要把一棵树分成若干条链,那么考虑每个子树 \(u\) 中,节点 \(u\) 的情况有三种:

  1. 执行了第一种操作,成为单独一个点。
  2. \(u\) 为链上的一个端点,显然不可能执行过第一次操作
  3. \(u\) 不为链上的端点,显然不可能执行过第一次操作

可以设 \(f_{u,0/1/2}\) 表示上面三种情况的最小操作次数。转移分类讨论,有:

\(f_{u,0}=\min(f_{v,0}-1,f_{v,2})+d_u+1\),没有 \(f_{v,1}\) 转移的原因是 \(f_{v,1}>f_{v,2}\)。

\(f_{u,1}=\sum_{v}f_{v,0}-\max(f_{v,0}-f_{v,1})\),这块求差值常用。

\(f_{u,2}=f_{u,1}-sec\)。

\(sec\) 表示 \(\max(f_{v,0}-f_{v,1})\) 的次大值。最后答案就是每个树的 \(\min(f_{u,0},f_{u,2})\) 加上连通块数量-1。

复杂度 \(O(n)\)。

#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define fi first
#define se second
#define pb push_back

typedef long long i64;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e6 + 10;
int n, m, ans, sum, cnt = 1;
bool vis[N];
int d[N];
struct node {
	int to, nxt;
} e[N << 1];
int h[N];
void add(int u, int v) {
	e[++cnt].to = v;
	e[cnt].nxt = h[u];
	h[u] = cnt;
}
int f[N][3];
void dfs(int u, int fa) {
	vis[u] = 1;
	int mx = 0, sec = 0;
	for(int i = h[u]; i; i = e[i].nxt) {
		int v = e[i].to;
		if(v == fa) continue;
		dfs(v, u);
		int dt = f[v][0] - f[v][1];
		if(dt > mx) sec = mx, mx = dt;
		else if(dt > sec) sec = dt; 
		f[u][0] += std::min(f[v][0] - 1, f[v][2]);
		f[u][1] += f[v][0];
	}
	f[u][0] += d[u] + 1;
	f[u][1] -= mx;
	f[u][2] = f[u][1] - sec;
}
void Solve() {
	std::cin >> n >> m;
	for(int i = 1; i <= m; i++) {
		int u, v;
		std::cin >> u >> v;
		add(u, v), add(v, u);
		d[u]++, d[v]++;
	}
	for(int i = 1; i <= n; i++) {
		if(vis[i]) continue;
		sum++;
		dfs(i, 0);
		ans += std::min(f[i][0], f[i][2]);
	}
	std::cout << ans + sum - 1 << "\n";
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
	Solve();

	return 0;
}

标签:02,int,P8595,KDOI,sec,dt,mx,define
From: https://www.cnblogs.com/FireRaku/p/18147513

相关文章

  • 2023 5月 dp做题记录
    目录5月dp做题记录P1064[NOIP2006提高组]金明的预算方案P1941[NOIP2014提高组]飞扬的小鸟P2679[NOIP2015提高组]子串P1850[NOIP2016提高组]换教室P2831[NOIP2016提高组]愤怒的小鸟P5020[NOIP2018提高组]货币系统P6064[USACO05JAN]NaptimeGP9344去年天......
  • 2023 6月 dp做题记录
    目录6月dp做题记录P5664[CSP-S2019]Emiya家今天的饭P8867[NOIP2022]建造军营[ARC115E]LEQandNEQP3800Power收集P3594[POI2015]WIL6月dp做题记录P5664[CSP-S2019]Emiya家今天的饭分析条件,我们要选出来的菜的集合需要满足的限制,集合不为空和烹饪方法互不相同都好......
  • 2023 7月 dp做题记录
    目录7月dp做题记录TheBakeryP5785[SDOI2012]任务安排P3195[HNOI2008]玩具装箱P3648[APIO2014]序列分割7月dp做题记录TheBakery这道题的状态转移并不难列,经典的分段问题,设状态\(dp_{i,j}\)表示前\(i\)个数字分了\(j\)段的最大价值,转移可以写成\(dp_{i,j}=\max(......
  • FineReport11 报表技巧02- 实现类Excel表头筛选功能
    背景:在报表开发中,有的需求方用习惯Excel的表头筛选时,就不太习惯帆软的特意点击报表控件进行筛选,希望报表筛选方式可以类似Excel那种直接在表头进行筛选的功能最终效果如下:实现步骤:1.1、数据集准备产品信息表:SELECT客户,产品,数量,cast(下单时间asdate)as下单时间,下单......
  • 20240419
    T1NFLSOJP3581Nomorexorproblems,please!实际上是异或和是最小公倍数的倍数。我们知道异或的结果二进制位数小于等于原来的。如果两个数没有倍数关系,则其最小公倍数一定不整除其异或和,因为最小公倍数的二进制位数至少多\(1\)。所以合法的子集要么异或和为\(0\),要么一个......
  • P321. [NOI2002]荒岛野人Savage题解?!!!
    还是我容易(☚xzz说的)想出,x年后i号野人的位置为:\((C_i+P_i*x)\modm\)我们只要让任意方程:\((C_i+P_i*x)\modm=(C_j+P_j*x)\modm\)解小于\(L_i\)或小于\(L_j\)即可推式子!\[(C_i+P_i*x)≡(C_j+P_j*x)\(mod~m)\\⇿x*(P_i-P_j)+y*m=C_j-C_i\]然后就是拓展欧几里得模板了。......
  • 2024/4/19日团队开发
    讨论:1、产品的运行以及功能​ 具体要做的可以让玩家体验一些事情或讲述一些事情,然后从他所做或者所选答案方向来评判这个人的得分,直接答题效果不太好。​ 基本完成网络安全测评以及人文科技体验,有时间尽量完成一下心理健康测评。​ 手机号登录注册,以及测评结果通过信息发送......
  • 题解:CSP-S2020] 函数调用
    题解:CSP-S2020]函数调用一句话题意:给定一个有初始值的序列,支持如下三种操作:1、单点加2、全局乘3、递归某些操作1、2、3求最终的序列。标签:topsort,动态规划,转化贡献统计(集中贡献),主客翻转关于topsort:部分分里的树结构基本上直接暗示了正解要使用topsort,而且本来函......
  • 【STM32+HAL库】---- 驱动MAX30102心率血氧传感器
    硬件开发板:STM32F407VET6软件平台:cubemax+keil+VScode1MAX30102心率血氧传感器工作原理MAX30102传感器是一种集成了红外光源、光电检测器和信号处理电路的高度集成传感器,主要用于心率和血氧饱和度的测量。以下是MAX30102传感器的主要特点和工作原理:红外光源:MAX30102传感器......
  • 2024-04-19---中等题---移动石子直到连续(贪心)
    移动石子直到连续(贪心)题目:思路:这道题是有小技巧的,和一些棋盘题有些类似。利用贪心的极致选择,可以直接把情况划分完。最少的移动次数:当三个石子连续放置的时候,最小移动次数为0.当三个石子中只要有两个石子的距离小于2,即可只需移动另外一个石子1次完成。其他情况都是最小2......