
[CTSC1999][网络流24题]补丁VS错误
发布日期:2025-04-06 05:59:18
浏览次数:14
分类:精选文章
本文共 2153 字,大约阅读时间需要 7 分钟。
#洛谷P2761、vijos P1019、codevs1239、codevs2218#
题目大意
有n个错误,m个不同的补丁。每个补丁都有两个描述字符串:“+”和“-”。使用一个补丁的条件是当前的错误集合必须包含“+”字符串中所有的错误,但不包含“-”字符串中的任何错误。使用该补丁后,会修复“-”字符串中的所有错误,同时新增“+”字符串中的错误。每个补丁使用一次需要一定的时间,问最短需要多少时间才能修复所有错误。如果无法完成,输出0。
解题思路
状态表示:使用20位整数来表示n个错误,每一位代表一个错误状态。例如,第j位为1表示错误j存在,0表示修复。
状态转移:从一个状态u使用补丁i,可以得到状态to。判断条件是:
- u包含补丁i的“+”字符串中的所有错误。
- u不包含补丁i的“-”字符串中的任何错误。
- 使用补丁i后,修复“-”字符串中的错误,并新增“+”字符串中的错误。
最短路径算法:使用Dijkstra算法,找出从初始状态(全1)到目标状态(0)的最短路径。每个状态的距离记录最短时间。
优化技巧:使用优先队列处理状态,按时间优先处理。状态转移时,通过位运算高效判断。
代码实现
#include#include #include int n, m;int dis[1 << 21];bool vis[1 << 21];struct Buding { int t; int has, donthas, ac, wa; Buding(int t = 0) : has(0), donthas(0), ac(0), wa(0) {} Buding(int t, int h, int d, int a, int w) : has(h), donthas(d), ac(a), wa(w), t(t) {}};Buding e[m + 1];char b[30], f[30];std::queue q;int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= m; ++i) { scanf("%d %s %s", &e[i].t, b, f); e[i].has = 0; e[i].donthas = 0; for (int j = 0; j < n; ++j) { if (b[j] == '-') e[i].donthas |= 1 << j; if (f[j] == '-') e[i].ac |= 1 << j; } } int initial = (1 << n) - 1; dis[initial] = 0; vis[initial] = true; q.push(initial); while (!q.empty()) { int u = q.front(); q.pop(); if (dis[u] != dis[u]) continue; for (int i = 1; i <= m; ++i) { Buding &p = e[i]; if ((u & p.has) == p.has && (u & p.donthas) == 0) { int to = (p.wa | (~p.ac)) | p.has; if (dis[u] + p.t < dis[to]) { dis[to] = dis[u] + p.t; if (!vis[to]) { vis[to] = true; q.push(to); } } } } } if (dis[0] == 0x3f3f3f3f) puts("0"); else puts(dis[0]); return 0;}
代码解释
结构体定义:Buding
结构体存储补丁的相关信息,包括时间、错误掩码等。
输入处理:读取n和m,初始化补丁数组,读取每个补丁的参数,并根据描述字符串生成掩码。
初始化:将初始状态加入优先队列,距离设为0。
Dijkstra算法:处理队列中的每个状态,遍历所有补丁,判断是否可以使用,计算新状态并更新距离。
结果输出:检查目标状态的距离,如果为无穷大,输出0,否则输出最短时间。
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2025年05月12日 16时03分21秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Linux Shell——流程控制
2025-04-06
Linux Shell之三 高级变量及字符串
2025-04-06
Linux Shell编程新手入门教程(六)
2025-04-06
Linux Shell编程最重要的十个核心概念,零基础入门到精通,收藏这一篇就够了
2025-04-06
Linux Shell编程(19)——测试与分支
2025-04-06
Linux Shell脚本入门--grep命令详解
2025-04-06
Linux Shell脚本处理JSON字符串
2025-04-06
Linux Shell脚本通过参数名传递参数
2025-04-06
Linux Shell语言并发执行多条命令
2025-04-06
Linux signal
2025-04-06
Linux SNMP支持IPv6配置实战
2025-04-06
Linux Socket学习--域和套接口简介
2025-04-06
linux sort 用法
2025-04-06
Linux stat命令和AIX istat命令 (查看文件修改时间)
2025-04-06
Linux sudo命令详解
2025-04-06
Linux tail 命令详解
2025-04-06
linux tar 备份命令
2025-04-06
Linux tar解压缩命令使用详解
2025-04-06
Linux tcpdump -any抓的包转换成标准的pcap
2025-04-06