
P2515 [HAOI2010]软件安装(树形dp)
输入数据:读取输入数据,包括节点数 初始化数据结构:创建必要的数据结构,包括权重数组 构建邻接矩阵:根据输入的邻接关系,填充邻接矩阵 缩点处理:通过缩点算法(如 Floyd-Warshall 算法)进一步优化邻接矩阵,确保图的稀疏化处理。
发布日期:2021-05-08 21:51:13
浏览次数:13
分类:精选文章
本文共 3537 字,大约阅读时间需要 11 分钟。
软件安装与解题思路
软件安装
本文将介绍一个用于解决特定图论问题的软件安装步骤,主要针对强连通分量的处理。安装过程包括以下几个关键环节:
n
和边数 m
。w
、价值数组 v
、邻接矩阵 a
以及辅助数组 d
、b
、c
。a
,确保对称性。解题思路
本题的主要目标是对图中的强连通分量进行分析与处理。我们将采用以下方法来实现:
强连通分量缩点:首先,我们需要对图进行缩点处理,找到所有强连通分量。缩点的核心思想是将每个强连通分量用一个代表点来代替,从而简化后续的处理流程。
状态转移分析:
- 父节点传承:每个节点的选择会影响其子节点的状态,因此我们需要从父节点开始分析,并将其价值传递给子节点。
- 背包法应用:类似于完全背包问题,我们需要枚举当前节点的所有可能状态,并进行状态转移。
以下是具体的实现步骤:
缩点处理
void sd() { o = n; for (int i = 1; i <= o; i++) { for (int j = 1; j <= o; j++) { if (a[i][j] == 1 && a[j][i] == 1 && w[i] > 0 && w[j] > 0 && i != j) { o++; w[o] = w[i] + w[j]; v[o] = v[i] + v[j]; w[i] = w[j] = --o1; } if (a[d[j]][j] == 1 && a[j][d[j]] == 1 && w[d[j]] < 0 && w[j] > 0) { w[n - w[d[j]]] += w[j]; v[n - w[d[j]]] += v[j]; w[j] = w[d[j]]; } if (w[d[j]] < 0 && w[j] > 0) { if ((a[d[j]][j] == 1 && a[j][d[j]] == 0) || (a[d[j]][j] == 0 && a[j][d[j]] == 1)) { d[j] = n - w[d[j]]; } } } }}
状态转移
int dp(int x, int k) { if (f[x][k] > 0) return f[x][k]; if (x == 0 || k <= 0) return 0; f[b[x]][k] = dp(b[x], k); f[x][k] = f[b[x]][k]; for (int i = 0; i <= k - w[x]; i++) { f[c[x]][k - w[x] - i] = dp(c[x], k - w[x] - i); f[b[x]][i] = dp(b[x], i); f[x][k] = max(f[x][k], v[x] + f[c[x]][k - w[x] - i] + f[b[x]][i]); } return f[x][k];}
AC代码
#include#include using namespace std;int n, m, o, o1, w[1005], v[1005], d[1005], b[1005], c[1005], a[1005][1005], f[1005][1005];void sd() { o = n; for (int i = 1; i <= o; i++) { for (int j = 1; j <= o; j++) { if (a[i][j] == 1 && a[j][i] == 1 && w[i] > 0 && w[j] > 0 && i != j) { o++; w[o] = w[i] + w[j]; v[o] = v[i] + v[j]; w[i] = w[j] = --o1; } if (a[d[j]][j] == 1 && a[j][d[j]] == 1 && w[d[j]] < 0 && w[j] > 0) { w[n - w[d[j]]] += w[j]; v[n - w[d[j]]] += v[j]; w[j] = w[d[j]]; } if (w[d[j]] < 0 && w[j] > 0) { if ((a[d[j]][j] == 1 && a[j][d[j]] == 0) || (a[d[j]][j] == 0 && a[j][d[j]] == 1)) { d[j] = n - w[d[j]]; } } } }}int dp(int x, int k) { if (f[x][k] > 0) return f[x][k]; if (x == 0 || k <= 0) return 0; f[b[x]][k] = dp(b[x], k); f[x][k] = f[b[x]][k]; for (int i = 0; i <= k - w[x]; i++) { f[c[x]][k - w[x] - i] = dp(c[x], k - w[x] - i); f[b[x]][i] = dp(b[x], i); f[x][k] = max(f[x][k], v[x] + f[c[x]][k - w[x] - i] + f[b[x]][i]); } return f[x][k];}int main() { cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> w[i]; } for (int i = 1; i <= n; i++) { cin >> v[i]; } for (int i = 1; i <= n; i++) { cin >> d[i]; a[d[i]][i] = 1; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { for (int k = 1; k <= n; k++) { if (a[k][i] == 1 && a[i][j] == 1) { a[k][j] = 1; } } } } sd(); for (int i = 1; i <= o; i++) { if (w[i] > 0) { b[i] = c[d[i]]; c[d[i]] = i; } } cout << endl;}
感谢
感谢您的阅读。如果您有任何问题或需要进一步的帮助,请随时联系。
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2025年03月26日 22时02分38秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
HTTP 协议图解
2019-03-06
Python 简明教程 --- 20,Python 类中的属性与方法
2019-03-06
Python 简明教程 --- 21,Python 继承与多态
2019-03-06
KNN 算法-理论篇-如何给电影进行分类
2019-03-06
Spring Cloud第九篇 | 分布式服务跟踪Sleuth
2019-03-06
CODING 敏捷实战系列课第三讲:可视化业务分析
2019-03-06
使用 CODING DevOps 全自动部署 Hexo 到 K8S 集群
2019-03-06
工作动态尽在掌握 - 使用 CODING 度量团队效能
2019-03-06
CODING DevOps 代码质量实战系列最后一课,周四发车
2019-03-06
CODING DevOps 深度解析系列第二课报名倒计时!
2019-03-06
CODING DevOps 线下沙龙回顾二:SDK 测试最佳实践
2019-03-06
翻译:《实用的Python编程》03_01_Script
2019-03-06
数据结构第八节(图(下))
2019-03-06
基础篇:异步编程不会?我教你啊!CompletableFuture
2019-03-06
基于Mustache实现sql拼接
2019-03-06
气球游戏腾讯面试题滑动窗口解法
2019-03-06
POJ 2260 Error Correction 模拟 贪心 简单题
2019-03-06
POJ - 1328 Radar Installation 贪心
2019-03-06
CSUOJ Water Drinking
2019-03-06
自定义博客园博客的背景图片
2019-03-06