网络流二十四题——软件补丁问题

Luogu P2761 软件补丁问题 一道超蒻的蓝题

软件补丁问题

题目描述

T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放了 m 个补丁程序。
每一个补丁程序都有其特定的适用环境,某个补丁只有在软件中包含某些错误而同时又不包含另一些错误时才可以使用。一个补丁在排除某些错误的同时,往往会加入另一些错误。
换句话说,对于任意一个补丁 i,都有四个与之相应的集合 B1i,B2i,F1iF2i。仅当软件包含 B1i 中的所有错误,而不包含 B2i 中的任何错误时,才可以使用补丁 i。补丁 i 将修复软件中的某些错误集合 F1i,而同时加入另一些错误 F2i。另外,运行每个补丁都耗费一定的时间。
试设计一个算法,利用 T 公司提供的 m 个补丁程序将原软件修复成一个没有错误的软件,并使修复后的软件耗时最少。对于给定的 n 个错误和 m 个补丁程序,找到总耗时最少的软件修复方案。

输入格式

第一行有两个正整数 nmn 表示错误总数,m表示补丁总数。
接下来 m 行给出了 m 个补丁的信息。每行包括一个正整数,表示运行补丁程序 i 所需时间,以及两个长度为 n 的字符串。中间用一个空格符隔开。
第一个字符串中,如果第 k 个字符为 +,则表示第 k 个错误属于 B1i。若为 -,则表示第 k 个错误属于 B2i。若为 0,则第 k 个错误既不属于 B1i 也不属于 B2i,即软件中是否包含第 k 个错误并不影响补丁 i 的可用性。
第二个字符串中,如果第 k 个字符为 -,则表示第 k 个错误属于 F1i。若为 +,则表示第 k 个错误属于 F2i。若为 0,则第 k 个错误既不属于 F1i 也不属于 F2i,即软件中是否包含第 k 个错误不会因使用补丁 i 而改变。

输出格式

程序运行结束时,将总耗时数输出。如果问题无解,则输出 0

数据范围

对于 100% 的数据:1n201m100

题目大意

给定一个具有n个特征的状态,和两个字符串s1s2来表示B1i,B2i,F1i,F2i的信息,当且仅当当前的状态具有B1i中的所有状态,不含有B2i的任何状态时候;能够在t的代价下将n中的F1i去掉,引入F2i,求从初始状态全为1到最终状态全为0所需要的最小代价

分析

涉及到状态很容易就想到状态压缩,我们定义当前状态sta中二进制位下1表示含有当前错误,ViceVersa.

处理1

对于给出的字符串s1,我们将他压为一个二进制数,B11(+)表示要含有当前错误,B20(-)表示不能有当前错误
那么显而易见,当前状态能使用此补丁的充要条件为:
sta&B1==B1并且sta&B2==0

处理2

对于给出的字符串s2,同样做二进制化操作,f1中的1代表会消除sta在这个位置上的1f2中的1表示会带来sta在这个位置上的1,那么经过了我们处理过后,状态sta会变成:
首先带来f2的错误,sta|=f2
其次消除f1的错误,sta|=f1sta^=f1
(因为f1中所有的错误都会被消除,所以大可直接假设sta中含有所有f1的错误再消除)

处理3

既然要求最小的花费,又涉及到状态与状态之间转移的代价,那么很容易就想到用最短路,这里我用的是SPFADijkstra应该也是没问题的,但是没有尝试过。先把处理好的初始状态sta0入队,再按照正常的SPFA来做就行了,这里提一嘴个人很容易打错的点,就是只有转移的状态既能够带来更优的结果并且当前状态没有在更新队列里面的时候我们才将它入。这也是为什么q.push(v),vis[v]=1;放在了松弛条件if(dis[x]+p[i].w<dis[v])的里面

点击查看代码
void spfa()
{
memset(dis,0x7f,sizeof dis);
dis[start]=0;q.push(start);vis[start]=1;
while(!q.empty())
{
int x=q.front();
for(int i=1;i<=m;i++)
{
if(usable(x,i))
{
int v=trans(x,i);
if(dis[x]+p[i].w<dis[v])
{
dis[v]=dis[x]+p[i].w;
if(!vis[v]) q.push(v),vis[v]=1;;
}
}
}
vis[x]=0,q.pop();
}
}

Code

点击查看代码

It has come to an END

posted @   Hanggoash  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
动态线条
动态线条end
点击右上角即可分享
微信分享提示