Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算)

Description

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

Input

第 1 行有 2 个正整数 n 和 m,n 表示错误总数,m表示补丁总数,1<=n<=20, 1<=m<=100。接下来 m 行给出了 m 个补丁的信息。每行包括一个正整数,表示运行补丁程序 i 所需时间,以及 2 个长度为 n 的字符串,中间用一个空格符隔开。第 1 个字符串中,如果第 k 个字符 bk 为“+”,则表示第 k 个错误属于 B1[i],若为“-”,则表示第 k 个错误属于 B21[i],若为“0”,则第 k 个错误既不属于 B1[i]也不属于 B2[i],即软件中是否包含第 k 个错误并不影响补丁 i 的可用性。第 2 个字符串中,如果第 k 个字符 bk为“-”,则表示第 k 个错误属于 F1[i],若为“+”,则表示第 k 个错误属于 F2[i],若为“0”,则第 k 个错误既不属于 F1[i]也不属于 F2[i],即软件中是否包含第 k 个错误不会因使用补丁i 而改变。

Output

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

Sample Input

3 3

1 000 00-

1 00- 0-+

2 0-- -++

Sample Output

8

Http

Libre:https://loj.ac/problem/6009

Luogu:https://www.luogu.org/problem/show?pid=2761

Source

最短路径,位运算

解决思路

话说这不是一道最短路径的题目吗?为什么放在了网络流里面?不懂╮(╯▽╰)╭

我们用位运算的方式表示一个错误有没有修复。对于错误i,若第i-1位是1则表示该错误存在,否则表示不存在。而每一次转移就根据位运算的操作来判断是否满足某些错误存在而另一些错误不存在的情况。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; const int maxN=300;
const int maxM=maxN*maxN*2;
const int inf=2147483647; int n,m;
unsigned int B1[maxN];//B1,B2,F1,F2的意义与题目一样
unsigned int B2[maxN];
unsigned int F1[maxN];
unsigned int F2[maxN];
int Cost[maxN];
int Q[(1<<21)];
int Dist[(1<<21)];
bool inqueue[(1<<21)]; int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
char str[maxN];
scanf("%d%s",&Cost[i],str);
for (int j=0;j<n;j++)
if (str[j]=='+')
B1[i]=B1[i]|(1<<(j));//这里是标记某个错误是否出现,注意标号从0开始
else
if (str[j]=='-')
B2[i]=B2[i]|(1<<j);
scanf("%s",str);
for (int j=0;j<n;j++)
if (str[j]=='+')
F1[i]=F1[i]|(1<<j);
else
if (str[j]=='-')
F2[i]=F2[i]|(1<<j);
}
for (int i=0;i<=(1<<n)-1;i++)
Dist[i]=inf;
int h=1,t=0;
Q[1]=(1<<n)-1;//开始时所有错误都存在
Dist[(1<<n)-1]=0;
inqueue[(1<<n)-1]=1;
do
{
t++;
int u=Q[t];
inqueue[u]=0;
for (int i=1;i<=m;i++)
{
unsigned int now=u;
if (((now&B1[i])==B1[i]) && (((~now)&B2[i])==B2[i]))//要满足B1[i]中的错误都存在且B2[i]中的错误都不存在才能加入该补丁
{
now=now&(~F2[i]);//先去掉该补丁修复的错误
now=now|F1[i];//再加上该补丁加上的错误
if (Dist[now]>Dist[u]+Cost[i])//更新最优值
{
Dist[now]=Dist[u]+Cost[i];
if (inqueue[now]==0)
{
h++;
Q[h]=now;
inqueue[now]=1;
}
}
}
}
}
while (h!=t);
if (Dist[0]==inf)//注意输出无解
cout<<0<<endl;
else
cout<<Dist[0]<<endl;
return 0;
}

Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算)的更多相关文章

  1. Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流)

    Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流) Description 问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同 ...

  2. Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流)

    Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流) Description G 公司有n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使n ...

  3. Libre 6012 「网络流 24 题」分配问题 (网络流,费用流)

    Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...

  4. Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流)

    Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流) Description W 公司有m个仓库和n个零售商店.第i个仓库有\(a_i\)个单位的货物:第j个零售商店需要\( ...

  5. Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)

    Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流) Description 给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开 ...

  6. Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流)

    Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流) Description 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. ...

  7. Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流)

    Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流) Description 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从 ...

  8. Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流)

    Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流) Description 问题描述: 给定正整数序列x1,...,xn . (1 ...

  9. Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流)

    Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流) Description 假设有来自n个不同单位的代表参加一次国际会议.每个单位的代表数分别为 ri.会议餐厅共有m张餐桌,每张餐桌 ...

随机推荐

  1. Android应用安全之数据传输安全

    Android软件通常使用WIFI网络与服务器进行通信.WiFi并非总是可靠的,例如,开放式网络或弱加密网络中,接入者可以监听网络流量:攻击者可能 自己设置WIFI网络钓鱼.此外,在获得root权限后 ...

  2. MiZ702学习笔记10——文本实例化IP的方法

    之前,添加vivado自带IP的时候,都是以图形化的方式:一般是新建一个Block Design顶层文件,然后将图形化的ip贴到,Block Design中. 但是,在进行PL的开发过程中,有时不想使 ...

  3. 洛咕 P3704 [SDOI2017]数字表格

    大力推式子 现根据套路枚举\(\gcd(i,j)\) \(ans=\Pi_{x=1}^nfib[x]^{\sum_{i=1}^{n/x}\sum_{j=1}^{n/x}[\gcd(i,j)=1]}\) ...

  4. CS100.1x-lab3_text_analysis_and_entity_resolution_student

    这次作业叫Text Analysis and Entity Resolution,比前几次作业难度要大很多.相关ipynb文件见我github. 实体解析在数据清洗和数据整合中是一个很重要,且有难度的 ...

  5. [LOJ#6066]. 「2017 山东一轮集训 Day3」第二题[二分+括号序列+hash]

    题意 题目链接 分析 首先二分,假设二分的答案为 \(mid\),然后考虑利用括号序列来表示树的形态. 点 \(u\) 的 \(k-\) 子树的括号序列表示实际上是刨去了 \(u\) 子树内若干个与 ...

  6. php faker 库填充数据

    Generating Fake Data in PHP with Faker 时间 2016-01-28 07:13:00 Wern Ancheta 原文  http://wern-ancheta.c ...

  7. SonarQube 平台搭建代码审查平台步骤

    SonarQube 平台1.下载包,安装启动2.在sonar.properties 配置mysql数据库的sonar.jdbc.username=sonarsonar.jdbc.password=so ...

  8. NodeMCU学习(一) : 开始之前的准备

    安装Aduino开发环境 在官网中下载Arduino开发环境,或者在网盘中下载: 网盘地址: https://pan.baidu.com/s/1OjMhYgKOYW69YC2dEwFgyw: 提取码: ...

  9. Dive查看docker镜像层信息

    1.主要采用docker运行dive的方式,不然宿主机还要安装go那些挺麻烦的.具体用法可查看官方: https://github.com/wagoodman/dive 2.拉取dive镜像 dock ...

  10. LintCode——Pour Water

    Pour Water: We are given an elevation map, heights[i] representing the height of the terrain at that ...