这个题目巧妙之处在于用二进制的每个位1,0分别表示bug的有无,以及实施补丁对相应bug的要求以及实施后的对bug的影响。

软件bug的状态:1表示相应bug仍然存在,0表示已经修复。这样可以将软件的状态用一个整数表示,例如1100(12)表示第1,2个bug存在,后面两个已经修复。

那么,对于n个bug 的软件,起点src = (1<<n)-1表示软件初始状态 111....111,终点sink = 0表示软件已经修复。

实施补丁的条件:

+-0 表示实施该补丁需要第1个bug存在,第2个bug不存在,对第三个无要求,可以用两个整数a1,a2表示,其中a1表示需要哪些bug存在,也就是对应字符串为'+'的地方,该整数的二进制位设为1,

其他位为0,这里为a1 = 100;a2表示哪些bug不能存在,对于字符串中'-'的位置a2相应二进制位设为0,其余为1,a2 = 101。这样判断某个软件当前状态(用整数x表示)是否符合实施补丁要求可以这样判断:

(x | a1) == x && (x & a2 )==x

补丁对bug的影响:

同样用两个整数b1,b2,表示方式和前面a1,a2一样,b1同a1,即'+'位设为1,其余为0;b2同a2,非'-'都设为1,'-'设为0。对于x实施补丁的过程就变成了:y = x,y |= b1,y &= b2.这样由状态x变成了y。

因此每个状态转化为一个整数,整个问题变成球一条从src,到sink的最短路,每条路的长度就是每个补丁花费的时间,dij可破之。

代码:

 #include <iostream>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define esp 1e-6
#define pb push_back
#define in freopen("in.txt", "r", stdin);
#define out freopen("out.txt", "w", stdout);
#define print(a) printf("%d\n",(a));
#define bug puts("********))))))");
#define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
#define inf 0x0f0f0f0f
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef vector<int>:: iterator IT;
typedef pair<int, int> pii;
#define N 30
#define M 200
#define MAX 10000000
char a[N], b[N];
int s[M][], t[M][], w[M];
int d[MAX], inq[MAX];
int n, m, src, sink;
priority_queue<pii, vector<pii>, greater<pii> > q;
void dij(void)
{
memset(d, 0x0f, sizeof(d));
// memset(inq, 0, sizeof(inq));
d[src] = ;
// inq[src] = 1;
q.push(make_pair(d[src], src));
while(!q.empty())
{
pii u = q.top();
q.pop();
int x = u.second;
if(d[x] != u.first)
continue;
for(int i = ; i < m; i++)
{
if(((x | s[i][]) == x) && ((x & s[i][]) == x))
{
int y = x;
y |= t[i][];
y &= t[i][];
if(d[x] + w[i] < d[y])
{
d[y] = d[x] + w[i];
q.push(make_pair(d[y],y));
}
}
}
}
}
int main(void)
{
int T = ;
while(scanf("%d%d", &n, &m),n+m)
{
memset(s, , sizeof(s));
memset(t, , sizeof(t));
src = (<<n) - ;
sink = ;
for(int i = ; i < m; i++)
{
scanf("%d%s%s", &w[i], a, b);
for(int j = ; j < n; j++)
{
if(a[j] == '+')
s[i][] |= (<<j);
if(a[j] != '-')
s[i][] |= (<<j);
if(b[j] == '+')
t[i][] |= (<<j);
if(b[j] != '-')
t[i][] |= (<<j);
}
}
dij();
printf("Product %d\n", T++);
if(d[] < inf)
printf("Fastest sequence takes %d seconds.\n", d[]);
else
puts("Bugs cannot be fixed.");
puts("");
}
return ;
}

UVA 658 It's not a Bug, it's a Feature!的更多相关文章

  1. UVa 658 - It's not a Bug, it's a Feature!(Dijkstra + 隐式图搜索)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. UVA 658 It's not a Bug, it's a Feature! (最短路,经典)

    题意:有n个bug,有m个补丁,每个补丁有一定的要求(比如某个bug必须存在,某个必须不存在,某些无所谓等等),打完出来后bug还可能变多了呢.但是打补丁是需要时间的,每个补丁耗时不同,那么问题来了: ...

  3. UVa 658 It's not a Bug, it's a Feature! (状态压缩+Dijstra)

    题意:首先给出n和m,表示有n个bug和m个补丁.一开始存在n个bug,用1表示一个bug存在0表示不存在,所以一开始就是n个1,我们的目的是要消除所有的bug, 所以目标状态就是n个0.对于每个补丁 ...

  4. UVA - 658 It's not a Bug, it's a Feature! (隐式图的最短路,位运算)

    隐式的图搜索,存不下边,所以只有枚举转移就行了,因为bug的存在状态可以用二进制表示,转移的时候判断合法可以用位运算优化, 二进制pre[i][0]表示可以出现的bug,那么u&pre[i][ ...

  5. [有意思]The IT workers of Star Wars -- That's not a bug. It's a feature

    Yeah, that Artoo is kinda mouthy... ... now select, "restore to factory settings." That'll ...

  6. poj1483 It's not a Bug, It's a Feature!

    It's not a Bug, It's a Feature! Time Limit: 5000MS   Memory Limit: 30000K Total Submissions: 1231   ...

  7. 【最短路】【位运算】It's not a Bug, it's a Feature!

    [Uva658] It's not a Bug, it's a Feature! 题目略 UVA658 Problem PDF上有 试题分析:     本题可以看到:有<=20个潜在的BUG,那 ...

  8. UVa 658 (Dijkstra) It's not a Bug, it's a Feature!

    题意: 有n个BUG和m个补丁,每个补丁用一个串表示打补丁前的状态要满足的要求,第二个串表示打完后对补丁的影响,还有打补丁所需要的时间. 求修复所有BUG的最短时间. 分析: 可以用n个二进制位表示这 ...

  9. 【uva 658】It's not a Bug, it's a Feature!(图论--Dijkstra或spfa算法+二进制表示+类“隐式图搜索”)

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

随机推荐

  1. RabbitMQ 原文译03--发布和订阅

    发布/订阅 在之前的案例中我们创建了一个工作队列,这个工作队列的实现思想就是一个把每一个任务平均分配给每一个执行者,在这个篇文章我们会做一些不一样的东西,把一个消息发送给多个消费者,这种模式就被称作& ...

  2. Sqlserver基于流程控制

    流程控制语句只能在单个批处理段,用户自定义函数和存储过程中使用不能夸多个批处理或者用户自定义函数或者存储过程 批处理:一个或者多个语句组成的一个批处理,是因为所有语句一次性地被提交到一个sql实例,如 ...

  3. oc语言学习之基础知识点介绍(一):OC介绍

      一.第一个OC程序 #import <Foundation/Foundation.h> //导入头文件 int main(int argc, const char * argv[]) ...

  4. 总结&记录

    一.Git(linux命令) 1.tar  压缩/解压 -c 建立一个压缩文件(create) -x 解压一个压缩文件 -t 查看tarfile中文件 -z 是否具有gzip的属性?是否需要用gzip ...

  5. Oracle之初始创建scott/tiger来测试

    在redhat5.5(32bit)上安装好oracle11g数据库软件,然后安装一个数据库,再然后登录数据库,创建scott/tiger测试 首先登录数据库,这里登录时是没有启动数据库的 [oracl ...

  6. iOS开发——屏幕尺寸适配

    对于屏幕尺寸适配,目前先指竖屏的方式适合方式1和2. 1.控件尺寸写死的方式,偶尔会用到屏幕的宽度和高度. UILabel *holdLabel = [[UILabel alloc]initWithF ...

  7. C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式)

    学习书籍: <C#本质论> 1--C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是 ...

  8. html-----017

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. OpenJudge/Poj 2013 Symmetric Order

    1.链接地址: http://bailian.openjudge.cn/practice/2013 http://poj.org/problem?id=2013 2.题目: Symmetric Ord ...

  10. mysql密码忘记后重置密码

    之前在centOS里安装了xampp,设置了mysql数据库root密码,今天需要增加个数据库,发现忘记之前设置的密码是什么了.经过一番摸爬滚打,终于搞明白了,注意以下的操作都是以linux的root ...