UVA 658 It's not a Bug, it's a Feature!
这个题目巧妙之处在于用二进制的每个位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!的更多相关文章
- 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& ...
- UVA 658 It's not a Bug, it's a Feature! (最短路,经典)
题意:有n个bug,有m个补丁,每个补丁有一定的要求(比如某个bug必须存在,某个必须不存在,某些无所谓等等),打完出来后bug还可能变多了呢.但是打补丁是需要时间的,每个补丁耗时不同,那么问题来了: ...
- 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.对于每个补丁 ...
- UVA - 658 It's not a Bug, it's a Feature! (隐式图的最短路,位运算)
隐式的图搜索,存不下边,所以只有枚举转移就行了,因为bug的存在状态可以用二进制表示,转移的时候判断合法可以用位运算优化, 二进制pre[i][0]表示可以出现的bug,那么u&pre[i][ ...
- [有意思]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 ...
- 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 ...
- 【最短路】【位运算】It's not a Bug, it's a Feature!
[Uva658] It's not a Bug, it's a Feature! 题目略 UVA658 Problem PDF上有 试题分析: 本题可以看到:有<=20个潜在的BUG,那 ...
- UVa 658 (Dijkstra) It's not a Bug, it's a Feature!
题意: 有n个BUG和m个补丁,每个补丁用一个串表示打补丁前的状态要满足的要求,第二个串表示打完后对补丁的影响,还有打补丁所需要的时间. 求修复所有BUG的最短时间. 分析: 可以用n个二进制位表示这 ...
- 【uva 658】It's not a Bug, it's a Feature!(图论--Dijkstra或spfa算法+二进制表示+类“隐式图搜索”)
题意:有N个潜在的bug和m个补丁,每个补丁用长为N的字符串表示.首先输入bug数目以及补丁数目.然后就是对M个补丁的描述,共有M行.每行首先是一个整数,表明打该补丁所需要的时间.然后是两个字符串,第 ...
随机推荐
- gd库复制图片做水印
将复制源图片的某个位置复制到目标图片中,不能调整大小 imagecopy(目标图片画布,复制源画布,目标画布左上角x,y,源画布左上角x,y,复制图片的宽,高); 允许调整大小 imagecopyre ...
- hdoj1584 蜘蛛牌 (区间型动态规划)
hdoj1584 分析: f[i][j] 表示 把一串牌 牌 i 到 j 摞为一摞时 所花费最少的步数. d[i][j] 表示把牌 i 挪到牌 j 上时需要走的步数(最初给的状态). 以一串牌 3~8 ...
- shell脚本实例(2)
1.传给脚本一个参数:目录,输出该目录中文件最大的,文件名和文件大小 #!/bin/bash if [ $# -ne 1 -o ! -d $1 ];then echo "Args is er ...
- Javascript原型钩沉
写在前面的总结: JS当中创建一个对象有好几种方式,大体上就是以下几种: ①通过var obj ={...} 这种方式一般称为字面量方式,{}直接写需要定义的字段 ②var obj = new Obj ...
- 复制pdf文字出来是乱码的一种可能的解决方案
最近在处理一个pdf文件,是一个地图文件,上面带各种文字的标注,地图比较大,而且文字信息比较多而且分散.因为字体的问题,在我的windows电脑上虽然可以正常显示,但是复制出来的文字都是方块,而且对应 ...
- 解决Asp.net中的Chart控件运行出现错误提示“ ChartImg.axd 执行子请求时出错”
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABTkAAAJwCAIAAADN5fIdAAAgAElEQVR4nOzdfZAc1X3o/VNFlbcoJf
- 取A表数据,关联B表任意一条数据
表A=================== AID, AName 1 jack 2 mary 3 lily 表B================== BID, AID, BName 1 1 aaa ...
- PRINTDLG 结构体
//包含 PrintDlg 函数用来初始化Print Dialog Box的信息,在用户关闭窗口后,返回用户选择的信息typedef struct tagPD { DWORD lStructSize; ...
- iOS开发——推送证书
(最近准备考试……空闲截图整理成博客)
- JS代码大全 (都是网上看到 自己整理的)
事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture(); event. ...