当前位置: 首页 > news >正文

P14309 【MX-S8-T2】配对题解

题目链接

题目大意

给定\(n\)个点的树,每条边有边权,每个点有一个参数\(c_i\),若\(c_i =1\),表示被用于配对,每个点只能配对一次,若能配对,则必须配对。每一次配对,会给\(r\)加上两个点之间的距离。可以交换一次\(c_i\),求\(r\)的最小值。

数据范围:\(2 \leq n \leq 10^6\)\(1 \leq w_i \leq 10^9\)\(c_i \in \{0, 1\}\)\(1 \leq u_i, v_i \leq n\)

解题思路

由于本篇题解是参照第一篇题解,因此同样钦定\(c\)为0的点为白点,否则为黑点

关键观察

通过手玩样例,我们可以意识到如果不进行交换,则在最优方案下,两个配对的黑点之间一定不会有其他未配对的黑点

再通过一定的思考,我们就可以得出,在最优方案下,每一棵子树内最多只剩下一个还未被匹配的黑点。进一步的,我们可以发现,一条边如果能产生贡献,当且仅当这个子树内有奇数个黑点。那么,答案仅与每个子树黑点个数的奇偶性相关

至此,我们有了更高效的计算方式

状态设计

考虑各个操作对答案的影响:

删除

从这个节点到根路径上的所有节点取反

交换

考虑交换\(i,j\),那么就是从\(i\)\(j\)路径上的所有点取反。其中,特别的,两点的LCA不变

接下来是第一篇题解的精妙之处:其设计了\(f_{i,x,y}\),表示\(i\)节点,取反\(x\)个黑点和\(y\)个白点的最小贡献

通过这种方式,使得官方题解中的八个近乎猎奇的状态变成了类似与背包的状态,更加易于思考,转移

状态转移

有了上面的状态,转移并不算难

我们可以枚举自身和儿子的状态进行转移

钦定当前考虑转移的状态为:\(f_{u,a_u,b_u}\)\(f_{v,a_v,b_b}\),那么转移就显然为\(f_{u,a_u+a_v,b_u+b_v}=f_{u,a_u,b_u} + f_{v,a_v,b_b} + w \times (size_v+b_u+b_v) mod 2\),在这里,\(size_i\)表示\(i\)为根的子树内的黑点总数

初始状态:\(f_{i,0,0}=0\),当前点为黑点,则有\(f_{i,1,0} =0\),否则有\(f_{i,0,1}=0\)

注意:由于这个DP非常像背包,因此需要用\(g\)来辅助转移,否则会出现前面的转移影响后面的情况

具体实现看代码

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define IOS ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define FailureG(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define pii pair<int,int>
#define fi first
#define se second
namespace WinterXorSnow{const int N = 1e6 + 10;vector< pair < ll , ll > > G[N];ll f[N][3][2],g[N][3][2];int n;ll siz[N],c[N];void dfs(int u,int fa){siz[u] = c[u];for(auto [v,w] : G[u]){if(v == fa) continue;dfs(v,u);siz[u] += siz[v];}return ;}void solve(int u,int fa){f[u][0][0] = 0;if(c[u]) f[u][1][0] = 0;else f[u][0][1] = 0;for(auto [v,w] : G[u]){memset(g[u],0x3f,sizeof g[u]);if(v == fa) continue;solve(v,u);for(int a1 = 0;a1 <= 2;a1 ++){for(int b1 = 0;b1 <= 1;b1 ++ ){for(int a2 = 0;a2 <= 2;a2 ++ ){for(int b2 = 0;b2 <= 1;b2 ++ ) {int x,y;x = a1 + a2;y = b1 + b2;if(x > 2 || y > 1) continue;g[u][x][y] = min(g[u][x][y],f[v][a2][b2] + f[u][a1][b1] + w * ((siz[v] - a2 + b2 + 2) % 2));}}}}memcpy(f[u],g[u],sizeof g[u]);}return ;}void work(){cin >> n;for(int i=1;i<=n;i++)cin  >> c[i];for(int i=1;i<n;i++){ll u,v,w; cin >> u >> v >> w;G[u].push_back({v,w});G[v].push_back({u,w});}dfs(1,0);memset(f,0x3f,sizeof f);solve(1,0);if(siz[1] & 1) cout << min(f[1][1][0],f[1][2][1]);else cout << min(f[1][0][0],f[1][1][1]);}
}
int main()
{IOS;WinterXorSnow::work();return 0;
}
http://www.hn-smt.com/news/374/

相关文章:

  • 想让默认头像不再千篇一律,就顺手复刻了一下 GitHub 的思路
  • java(3)基础规范
  • 读书日记3
  • Tuack 生成 OI 比赛题目 PDF 笔记
  • 数据库三大范式、Union和Union all的区别
  • CSP-S2025 游记
  • 「LG3600-随机数生成器」题解
  • MathType7下载包安装教程2025最新下载+安装+汉化激活(附安装包,超详细)
  • 2025强网杯ezphp复现
  • 漏洞报告被拒绝的常见原因及避免方法
  • 【IEEE出版 | 重庆邮电大学主办 | 多届次、高层次】第六届人工智能与计算机工程国际学术会议(ICAICE 2025)
  • Docker容器里面部署的Jenkins的Java17升级到21版本(无需删除之前容器,内部在线升级) - 攻城狮
  • 报表知识
  • 渐进过程中大O与小o混用
  • 消息队列的有序性
  • 【LTDC】DMA2D —— 嵌入式系统的 GPU
  • unity管理器设计:Manager of Managers
  • iview table 排序 columns 里面写 sortable: custom 不要写 sortable: true 不然会进行二次内部排序序号等 字段。
  • 本地运行nginx服务,模拟线上环境访问项目
  • git提交远程项目步骤
  • 2025 年搅拌器搅拌设备,侧入式搅拌设备,斜插式揽拌设备,卧式搅拌设备厂家最新推荐,聚焦资质、案例、售后的五家企业深度解读
  • 2025 年环保搅拌设备,搅拌装置设备,框式搅拌设备厂家最新推荐,实力品牌深度解析采购无忧之选!
  • CorelDRAW的shell扩展ShellXP.dll导致资源管理器explorer.exe卡死/冻结/无响应/挂起
  • 2025 年定制矿车,大型矿车,固定式矿车厂家最新推荐,产能、专利、环保三维数据透视
  • 醒图电脑版下载与安装教程(2025最新版)
  • 2025 年江苏电缆附件,热缩电缆附件,冷缩电缆附件,预制电缆附件厂家最新推荐,产能、专利、环保三维数据透视
  • Android Studio 使用glibc2.28的版本
  • 2025年10月兰花油品牌推荐榜:五款精华油深度对比与选购指南
  • 2025年浅拾兰花双萃致臻精华油:从成分与技术维度解析其护肤功效
  • 2025 年进口螺杆泵,萨伯特螺杆泵,污泥螺杆泵厂家最新推荐,实力品牌深度解析采购无忧之选!