P2761 软件补丁问题

P2761 软件补丁问题

思路

貌似不用网络流,直接状态压缩
用spfa跑最短路,直接判断是否能过
位运算太渣了,WA了好几发

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 21, M = 101, inf = 0x3f3f3f3f;
int read() {
    int x = 0, f = 1; char s = getchar();
    for(; s > '9' || s < '0'; s = getchar()) if(s == '-') f = -1;
    for(; s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0';
    return x * f;
}
int n, m, tim[M], dis[1<<N], b1[M], b2[M], f1[M], f2[M];
bool vis[1<<N];
char s[N];
void spfa() {
    memset(dis, 0x3f, sizeof(dis));
    dis[(1<<n)-1] = 0;
    queue<int> q;
    q.push((1<<n)-1);
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        vis[u] = 0;
        for(int i = 1; i <= m; ++i) {
            int v = (u & (~f1[i])) | f2[i];
            if(dis[v] > dis[u] + tim[i]) {
                if((u & b2[i]) == 0 && ((u | b1[i]) == u)) {
                    dis[v] = dis[u] + tim[i];
                    if(!vis[v]) {
                        vis[v] = 1;
                        q.push(v);
                    }
                }
            }
        }
    }
}
int main() {
    n = read(), m = read();
    for(int i = 1; i <= m; ++i) {
        tim[i] = read();
        scanf("%s", s);
        for(int j = 0; j < n; ++j) {
            if(s[j] == '+') b1[i] |= (1<<j);
            else if(s[j] == '-') b2[i] |= (1<<j);
        }
        scanf("%s", s);
        for(int j = 0; j < n; ++j) {
            if(s[j] == '-') f1[i] |= (1<<j);
            else if(s[j] == '+') f2[i] |= (1<<j);
        }
    }
    spfa();
    if(dis[0] == inf) dis[0] = 0;
    printf("%d\n", dis[0]);
    return 0;
}

原文地址:https://www.cnblogs.com/lovedsr/p/10188708.html

时间: 2024-10-09 03:11:56

P2761 软件补丁问题的相关文章

[Luogu P2761] 软件补丁问题

Description T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放了一批共 m 个补丁程序.每一个补丁程序都有其特定的适用环境,某个补丁只有在软件中包含某些错误而同时又不包含另一些错误时才可以使用.一个补丁在排除某些错误的同时,往往会加入另一些错误. 换句话说,对于每一个补丁 i,都有 2 个与之相应的错误集合 B1[i]和 B2[i],使得仅当软件包含 B1[i]中的所有错误,而不包含 B2[i]中的任何错误时,才可以使用补丁 i.补丁 i 将修复软件中的某些错误 F1[i

洛谷 P2761 软件补丁问题 【spfa】

-为什么最短路的题会出现在网络流24里?? 因为范围是15所以直接把每个状态作为一个点,向它能转移到的点连有向边即可.可以不用建图(据说建图存不下?),直接枚举m个转移方案.位运算比较麻烦注意不要写错. #include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; const int N=1500005,inf=1e9; int n,m,d

P2761 软件补丁问题 【状压】【最短路】

输入输出样例 输入 #1复制 3 3 1 000 00- 1 00- 0-+ 2 0-- -++ 输出 #1复制 8 思路 为啥会有网络流的tag wa了5发感觉怎么建图都不对 一看都是状压最短路 打了个dijRE了 发现好像边太多 看别人都用的spfa莽,干脆我也莽一发好了 大家都知道spfa的核心就是边建图边松弛 如何建图: 因为对于第 i 个错误来说,只存在‘待修复’和‘已修复’两种状态 为了方便枚举,对状态进行压缩成一个整数来枚举 因为可能成环,显然状压dp很难处理这类问题 考虑用spf

软件补丁制作工具箱 v 1.0

想学习软件补丁制作的网友可以下载看看. https://pan.baidu.com/s/1c1T0j5I

【网络流24题】软件补丁问题(最短路)

[网络流24题]软件补丁问题(最短路) 题面 COGS 题解 这题貌似和网络流没啥关系 因为错误很少 可以直接状压 然后利用位运算直接跑最短路就行了 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map&

COGS439. [网络流24题] 软件补丁

[问题描述] 对于一个软件公司来说,在发行一个新软件之后,可以说已经完成了工作.但是实际上,许多软件公司在发行一个新产品之后,还经常发送补丁程序,修改原产品中的错误(当然,有些补丁是要收费的). 如某微硬公司就是这样的一个软件公司.今年夏天,在发行了一个新的字处理软件之后,到现在他们已经编写了许多补丁程序.仅仅在这个周末,他们就用新编写的补丁程序解决了软件中的一个大问题.而在每一个补丁程序修改软件中的某些错误时,有可能引起软件中原来存在的某些错误重新发作.发生这种情况是因为当修改一个错误时,补丁

【网络流24题】 No.12 软件补丁问题(最小转移代价 最短路)

[题意] T 公司发现其研制的一个软件中有 n 个错误, 随即为该软件发放了一批共 m 个补丁程序. 每一个补丁程序都有其特定的适用环境, 某个补丁只有在软件中包含某些错误而同时又不包含另一些错误时才可以使用.一个补丁在排除某些错误的同时, 往往会加入另一些错误.换句话说, 对于每一个补丁 i, 都有 2 个与之相应的错误集合 B1[i]和 B2[i],使得仅当软件包含 B1[i]中的所有错误, 而不包含 B2[i]中的任何错误时, 才可以使用补丁 i. 补丁 i 将修复软件中的某些错误 F1[

软件补丁问题(SPFA+位运算)

洛谷P2761 1.考虑到所有的错误只有"修复,未修复"两种情况,所以可以用0,1标记压缩状态,采用位运算减少时空浪费. 又考虑到有修复时间的关系,将时间抽象成边,将状态抽象为点(设修复为0,未修复为1)最后从(1<<n)-1开始寻找到0的最短路,SPFA一边建图一边松弛即可. 2.实现过程中,难点在于对二进制表示,以及位运算组合判断的处理. 首先,状态要表示(见前): 其次,补丁b,f要表示. 最初考虑用两个数来表示b,f,发现受"不动错误"影响,无法

【网络流24题----04】软件补丁问题魔术球问题

问题描述: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为 1,2,3,4......的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在n根柱子上最多能放多少个球.例如,在4 根柱子上最多可放11个球. ´编程任务: 对于给定的n,计算在 n根柱子上最多能放多少个球. ´数据输入: 文件第1 行有 1个正整数n,表示柱子数. ´结果输出: 文件的第一行是球数. 数据规模 n<=60  保证答案小于16