关键词:状态压缩 最短路径

想不出快速办法,就先考虑考虑暴力。枚举每一种错误分布的情况,然后通过可用的补丁转化为另多种情况,这些情况又转化为更多种情况……我们可以用图来表示这种关系!

状态压缩:每个错误的状态可以压缩在一个整数里。

最短路径:如果一个状态可以用补丁变为另一种状态,则两个状态间连一条边,权值为补丁所需时间。

注意:二进制运算符,如&,|等,优先级比==低。所以有二进制运算时,等号左边记得要加括号。

#include <cstdio>
#include <cstring>
#include <cassert>
#include <iostream>
#include <queue>
#include <vector>
using namespace std; #define LOOP(i, n) for(int i=0; i<n; i++)
const int MAX_STATE = << , INF = 0x3f3f3f3f, MAX_BUG = , MAX_PATCH = ;
int TotBug, TotPatch;
int HaveBug[MAX_PATCH], Normal[MAX_PATCH], Repair[MAX_PATCH], Add[MAX_PATCH];
int W[MAX_PATCH]; struct Node;
struct Edge; struct Node
{
Edge *Head;
int Dist, State;
bool Inq;
Node() :Dist(INF){}
}_nodes[MAX_STATE];struct Edge
{
Node *To;
Edge *Next;
int Weight;
Edge(Node *to, Edge *next, int weight)
:To(to),Next(next),Weight(weight){}
};
vector<Edge*> _edges; void AddEdge(int uId, int vId, int weight)
{
Node *from = uId + _nodes, *to = vId + _nodes;
from->State = uId;
to->State = vId;
Edge *e = new Edge(to,from->Head,weight);
_edges.push_back(e);
from->Head = e;
} void Build(Node *cur)
{
LOOP(patch, TotPatch)
{
if (((cur->State & HaveBug[patch]) == HaveBug[patch]) && ((~cur->State) & Normal[patch]) == Normal[patch])
{
int newState = ((~Repair[patch])&cur->State) | Add[patch];
if (cur->State != newState)
AddEdge(cur->State, ((~Repair[patch])&cur->State) | Add[patch], W[patch]);
}
}
} void SPFA()
{
static queue<Node*> q;
int curState = ( << TotBug) - ;
Node *cur = curState + _nodes;
cur->State = curState;
cur->Dist = ;
Build(cur);
cur->Inq = true;
q.push(cur);
while (!q.empty())
{
cur = q.front();
q.pop();
if (cur->Inq)
cur->Inq = false;
for (Edge *e = cur->Head; e; e = e->Next)
{
if (cur->Dist + e->Weight < e->To->Dist)
{
if (e->To->Dist == INF)
Build(e->To);
e->To->Dist = cur->Dist + e->Weight;
if (!e->To->Inq)
{
e->To->Inq = true;
q.push(e->To);
}
}
}
}
} int main()
{
scanf("%d%d", &TotBug, &TotPatch);
char b[], f[];
LOOP(patch, TotPatch)
{
scanf("%d %s %s", &W[patch], b, f);
LOOP(bug, TotBug)
{
if (b[bug] == '+')
HaveBug[patch] |= ( << bug);
else if (b[bug] == '-')
Normal[patch] |= ( << bug);
if (f[bug] == '+')
Add[patch] |= ( << bug);
else if (f[bug] == '-')
Repair[patch] |= ( << bug);
}
}
SPFA();
printf("%d\n", _nodes[].Dist == INF ? : _nodes[].Dist);
return ;
}

luogu2761 软件补丁问题 状态压缩最短路径的更多相关文章

  1. POJ 3311 Hie with the Pie(DP状态压缩+最短路径)

    题目链接:http://poj.org/problem?id=3311 题目大意:一个送披萨的,每次送外卖不超过10个地方,给你这些地方之间的时间,求送完外卖回到店里的总时间最小. Sample In ...

  2. luogu2761 软件补丁问题

    状压最短路 #include <iostream> #include <cstring> #include <cstdio> #include <queue& ...

  3. uva658(最短路径+隐式图+状态压缩)

    题目连接(vj):https://vjudge.net/problem/UVA-658 题意:补丁在修正 bug 时,有时也会引入新的 bug.假定有 n(n≤20)个潜在 bug 和 m(m≤100 ...

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

    Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算) Description T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放 ...

  5. leetcode 864. 获取所有钥匙的最短路径(BFS,状态压缩)

    题目链接 864. 获取所有钥匙的最短路径 题意 给定起点,要求在最短步骤内收集完所有钥匙,遇到每把锁之前只有 有对应的钥匙才能够打开 思路 BFS+状态压缩典型题目 先确定起点和总的钥匙数目,其次难 ...

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

    [问题描述] 对于一个软件公司来说,在发行一个新软件之后,可以说已经完成了工作.但是实际上,许多软件公司在发行一个新产品之后,还经常发送补丁程序,修改原产品中的错误(当然,有些补丁是要收费的). 如某 ...

  7. P2761 软件补丁问题

    P2761 软件补丁问题 思路 貌似不用网络流,直接状态压缩 用spfa跑最短路,直接判断是否能过 位运算太渣了,WA了好几发 代码 #include <bits/stdc++.h> us ...

  8. [网络流24题] 洛谷P2761 软件补丁问题

    题意:某公司发现其研制的一个软件中有 n个错误,随即为该软件发放了一批共 m 个补丁程序.对于每一个补丁 i ,都有 2 个与之相应的错误集合 B1(i)和 B2(i),使得仅当软件包含 B1(i)中 ...

  9. uva658 dijkstra+状态压缩

    题目大意: 假定有n个潜在的bug和m个补丁,每个补丁用长为n的字符串表示.首先输入bug数目以及补丁数目.然后就是对m 个补丁的描述,共有m行.每行首先是一个整数,表明打该补丁所需要的时间.然后是两 ...

随机推荐

  1. Coursera公开课-Machine_learing:编程作业5

    Regularized Linear Regression and Bias/Variance 大多数时候,我们使用机器学习方法得到的结果都不是特别理想,常见 欠拟合 和 过拟合 问题.通过一些变量画 ...

  2. sql学习--update

    两种修改形式 第一种:静态插入 ,notes='began career selling ...balabala' where jc='johnny ca' 第二种: --注意别名和on后边的表连接不 ...

  3. 【PostgreSQL-9.6.3】函数(3)--日期和时间函数

    在PostgreSQL中,DATE.TIME.TIMESTAMP是三种不同的数据类型.DATE表示日期类型,格式为YYYY-MM-DD或YYYYMMDD:TIME表示时间类型,格式为hh:mi:ss: ...

  4. 对学Oracle数据库初学者的开场篇

    前言:因为项目原因,近期开始学习Oracle数据库.Oracle是目前最流行的数据库之一,功能强大,性能卓越,相对的学习的难度还是不小.我打算将自己的学习过程记录下来,做个积累,方便自己和其他的学习者 ...

  5. Android读写文件

    1.从resource中的raw文件夹中获取文件并读取数据(资源文件只能读不能写) String res = ""; try{ InputStream in = getResour ...

  6. 【C++】四种排序算法的时间比较

    四种排序算法的时间比较 [注]clock函数对输入(用户输入)元素N排序的计时 #include<iostream> #include<time.h> using namesp ...

  7. 07--c++类的构造函数详解

    c++类的构造函数详解 c++构造函数的知识在各种c++教材上已有介绍,不过初学者往往不太注意观察和总结其中各种构造函数的特点和用法,故在此我根据自己的c++编程经验总结了一下c++中各种构造函数的特 ...

  8. nim游戏解法(转)

    转自:http://acm.hdu.edu.cn/forum/read.php?fid=9&tid=10617 取火柴的游戏 题目1:今有若干堆火柴,两人依次从中拿取,规定每次只能从一堆中取若 ...

  9. Having子句用法

    Having基础用法 集合结果指定条件 注:HAVING子句中能够使用三种要素:常数,聚合函数,GROUP BY子句中指定的列名(聚合建) HAVING子句: 用having就一定要和group by ...

  10. esp32(M5STACK)程序烧写(Ubuntu)

    由于我们的开发环境在Ubuntu上,所以介绍一下如何在Ubuntu上烧写esp32的程序 首先下载esptools   pip install esptool           擦除 sudo es ...