这个题目巧妙之处在于用二进制的每个位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. js运动

    一.offsetWidth / offsetHeight 获取整个块的宽度/高度,包括border 二.clientWidth / clientHeight 获取块的宽度/高度,不包括border 三 ...

  2. 20160510--hibernate懒加载问题

    懒加载 通过asm和cglib二个包实现:Domain是非final的. 1.session.load懒加载. 2.one-to-one(元素)懒加载: 必需同时满足下面三个条件时才能实现懒加载 (主 ...

  3. MySQL支持多种存储引擎

    MySQL的强大之处在于它的插件式存储引擎,我们可以基于表的特点使用不同的存储引擎,从而达到最好的性能. MySQL有多种存储引擎:MyISAM.InnoDB.MERGE.MEMORY(HEAP).B ...

  4. LaTeX Pdf to Word

    用LaTeX写的文稿,生成的pdf,如果要改成word文档,如何是最合适的方式? 查了很多帖子,比较靠谱的一种方式是先将pdf转成rtf格式,再用word打开rtf文件.也有直接从tex文件直接转成d ...

  5. 取A表数据,关联B表任意一条数据

     表A=================== AID, AName 1 jack 2 mary 3 lily 表B================== BID, AID, BName 1 1 aaa ...

  6. oracle随笔(转)

    ---------数学函数 1.绝对值S:select abs(-1) valueO:select abs(-1) value from dual 2.取整(大)S:select ceiling(-1 ...

  7. Android笔记之adb命令解析1

    要在cmd命令中直接使用adb,需要配置环境变量:目录XXX\sdk\platform-tools 查看adb -help 帮助命令打印出以下内容: Android Debug Bridge vers ...

  8. java多线程 join方法以及优先级方法

    /*join:当A线程执行到了B线程的.join()方法时,A就会等待.等B线程都执行完,A才会执行. join可以用来临时加入线程执行. 1.线程使用join方法,主线程就停下,等它执行完,那么如果 ...

  9. WPF 程序中启动和关闭外部.exe程序

    当需要在WPF程序启动时,启动另一外部程序(.exe程序)时,可以按照下面的例子来: C#后台代码如下: using System; using System.Collections.Generic; ...

  10. mysql学习笔记4

    用phpmyadmin创建数据库时出现 #1064 - You have an error in your SQL syntax; check the manual that corresponds ...