[网络流24题] 软件补丁问题

题目链接:戳我
感觉虽然在所谓的网络流24题编制里,但是并没有看出来怎么用网络流做?(听说网络流24题全名不叫网络流24题???
看到n的范围挺小的,我们考虑状压。
转移的过程可以放到图论里面,因为要求费用最小,所以我们想到了最短路!(笑
所以就是dij+状压转移嘛qwqwq(我就是不写spfa!!!
注意一下非法情况的判断为f1里面包含,但是当前情况u不包含。或者f2里面不包含当前情况却包含了。
转移的下一个状态v对于f1的修改情况,我们这里采用减法操作,但是一定要判断这一位上是否有1再减去!(有可能本来就没有这个漏洞,所以就不需要修补啊qwq)
开始的情况为dis[(1<<n)-1],结束的情况为dis[0]。
代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,t,T;
char cur1[21],cur2[21];
struct Node
{
    int u,d;
    friend bool operator <(struct Node x,struct Node y){return x.d>y.d;}
};
int head[1050000],dis[1050000],done[1050000],b1[110][21],b2[110][21],f1[110][21],f2[110][21],cost[110];
inline bool check(int now,int x)
{
    for(int i=0;i<n;i++)
    {
        if(b1[x][i]==1&&!(now&(1<<i))) return false;
        if(b2[x][i]==1&&(now&(1<<i))) return false;
    }
    return true;
}
inline void dij()
{
    priority_queue<Node>q;
    memset(dis,0x3f,sizeof(dis));
    q.push((Node){T,0}),dis[T]=0;
    while(!q.empty())
    {
        int u=q.top().u; q.pop();
        if(done[u]) continue;
        done[u]=1;
        for(int i=1;i<=m;i++)
        {
            if(check(u,i)==false) continue;
            int v=u;
            for(int j=0;j<n;j++)
            {
                if(f1[i][j]) v-=v&(1<<j);
                if(f2[i][j]) v|=1<<j;
            }
            if(dis[v]>dis[u]+cost[i])
                dis[v]=dis[u]+cost[i],q.push((Node){v,dis[v]});
        }
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d",&n,&m);
    T=(1<<n)-1;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%s%s",&cost[i],cur1,cur2);
        int len1=strlen(cur1),len2=strlen(cur2);
        for(int j=0;j<len1;j++)
        {
            if(cur1[j]=='+') b1[i][j]=1;
            if(cur1[j]=='-') b2[i][j]=1;
        }
        for(int j=0;j<len2;j++)
        {
            if(cur2[j]=='-') f1[i][j]=1;
            if(cur2[j]=='+') f2[i][j]=1;
        }
    }
    dij();
    printf("%d\n",dis[0]==0x3f3f3f3f?0:dis[0]);
}

原文地址:https://www.cnblogs.com/fengxunling/p/10291309.html

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

[网络流24题] 软件补丁问题的相关文章

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

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

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

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

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

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

BZOJ_1221_ [HNOI2001]_软件开发(网络流24题,最小费用流)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1221 n天,每天需要r个毛巾,用完以后可以洗,要么花fa洗a天,要么花fb洗b天,毛巾不够了可以话f买一个,问最少需要多少钱. 分析 把每天拆成两个点:x[i]表示第i天的脏毛巾,y[i]表示第i天要用的毛巾. 1.s向x[i]连弧,容量为r[i],花费为0,表示每天会用脏r[i]条毛巾. 2.x[i]向x[i+1]连弧(注意边界),容量为INF,花费为0,表示把第i天的脏毛巾搁置到第i+1

「网络流24题」 题目列表

「网络流24题」 题目列表 序号 题目标题 模型 题解 1 飞行员配对方案问题 二分图最大匹配 <1> 2 太空飞行计划问题 最大权闭合子图 <2> 3 最小路径覆盖问题 二分图最小路径覆盖 <3> 4 魔术球问题 <4> 5 圆桌问题 <5> 6 最长递增子序列问题 <6> 7 试题库问题 <7> 8 机器人路径规划问题 <8> 9 方格取数问题 二分图最大点权独立集 <9> 10 餐巾计划问题

网络流24题小结

网络流24题 前言 网络流的实战应用篇太难做了,因此先完善这一部分 ## 第一题:飞行员配对方案 \(BSOJ2542\)--二分图 最优匹配 题意 两国飞行员\(x\)集合\(y\)集合,\(x\)飞行员可以配对特定的\(y\)集合的飞行员(可无),求一对一配对最大数 Solution 二分图最大匹配裸题,最大流实现 建图:(设\(i\in x\)而\(i'\in y\)) \((S,i,1)~(i',T,1)\) 对\((i,j')\)可匹配\((i,j',1)\) Code 略 ## 第二

【网络流24题----14】孤岛营救问题

孤岛营救问题 Time Limit: 1 Sec  Memory Limit: 128 MB Description 1944年,特种兵麦克接到国防部的命令.要求马上赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到了迷宫的地形图.迷宫的外形是一个长方形,其南北方向被划分为 N行,东西方向被划分为 M列,于是整个迷宫被划分为 N×M个单元.每个单元的位置可用一个有序数对 (单元的行号,单元的列号)来表示.南北或东西方向相邻的 2个单元之间可能互

【网络流24题】

网络流 网络流24题 [最小路径覆盖问题] 关于输出路径,因为即使有反向弧经过左侧点也一定会改变左侧点的去向,若没连向右侧就会被更新到0,所以不用在意. mark记录有入度的右侧点,然后从没入度的右侧点开始把整条路径输出来即可. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=100000,inf=0x3f3f3f3f; int n,m,

【网络流24题】魔术球问题

P1226 - [网络流24题]魔术球问题 Description 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为 1,2,3,4......的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在n根柱子上最多能放多少个球.例如,在4 根柱子上最多可 放11个球. ′编程任务: 对于给定的n,计算在 n根柱子上最多能放多少个球. Input 第1 行有 1个正整数n,表示柱子数. Output 第一行是球