原题:Uva 658
程序代码
/*
①判定某些位置是否为1,如判定2、4位置为1,则转化为判断x|0101是否等于x。
②判定某些位置是否为0,如判定2、4位置为0,则转化为判断x&1010是否等于x。
③将某些位置转化为1,如2、4位置转化为1,则令x=x|0101。
④将某些位置转化为0,如2、4位置转化为0,则令x=x&1010。
*/
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N = (1<<20)+5,K=105,INF = 1<<30;
int d[N], s[K][2], t[K][2], w[K];
int n, m;
char s1[K], s2[K];
bool inque[N];
void spfa(int ss){
mem(inque,false);
queue<int> q;
q.push(ss);
inque[ss] = true;
d[ss] = 0;
while(!q.empty()){
int u = q.front();
q.pop();
inque[u] = false;
for(int i = 0; i < m; i++)
if(((u|s[i][0]) == u) && ((u&s[i][1]) == u))
{
int v = u|t[i][0];
v&=t[i][1];
if(d[v] > d[u] + w[i]){
d[v] = d[u]+w[i];
if(!inque[v]){
inque[v] = true;
q.push(v);
}
}
}
}
}
int main(){
int ct = 0;
while(~scanf("%d%d",&n, &m)){
if(n == 0 && m == 0) break;
printf("Product %d\n", ++ct);
mem(s,0);
mem(t,0);
for(int i = 0; i < m; i++){
scanf("%d%s%s",&w[i], s1, s2);
for(int j = 0; j < n; j++){
if(s1[j] == '+') s[i][0] |= (1<<j);
if(s1[j] == '+' || s1[j] == '0') s[i][1] |= (1<<j);
if(s2[j] == '+') t[i][0] |= (1<<j);
if(s2[j] == '+' || s2[j] == '0') t[i][1] |= (1<<j);
}
}
for(int i = 0; i < (1<<n); i++) d[i] = INF;
spfa((1<<n)-1);
if(d[0] == INF) puts("Bugs cannot be fixed.");
else printf("Fastest sequence takes %d seconds.\n", d[0]);
puts("");
}
return 0;
}