题意:某个软件有n个bug(n<=20)和m个补丁(m<=100),每个补丁可以修复某些bug,同时又会带来某些bug,而且每个补丁要能起效都必须满足某些条件:在安装此补丁前,必须有某些指定bug存在以及某些指定的bug不存在。
每个补丁都有一个安装时间,问最短需要多少时间才可以消除所有bug?
参考了大神的二进制表示的方法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 110;
const int MAXD = 2000000;
const int INF = 0x3f3f3f3f;
int s[2][MAXN],t[2][MAXN],w[MAXN],N,M;
char a[MAXN],b[MAXN];
int q[MAXD],inq[MAXD],d[MAXD];
int init(){
scanf("%d%d",&N,&M);
if (!M && !N)
return 0;
memset(s,0,sizeof(s));
memset(t,0,sizeof(t));
for (int i = 0; i < M; i++){
scanf("%d%s%s",&w[i],a,b);
for (int j = 0; j < N; j++){
if (a[j] == '+')
s[1][i] |= (1<<j);
if (a[j] == '-')
s[0][i] |= (1<<j);
if (b[j] == '+')
t[1][i] |= (1<<j);
if (b[j] == '-')
t[0][i] |= (1<<j);
}
}
return 1;
}
void SPFA(){
int Max = 1<<N;
for (int i = 0; i < Max; i++){
d[i] = INF;
inq[i] = 0;
}
int front=0,rear=0;
d[Max-1] = 0;
q[rear++] = Max - 1;
while (front != rear){
int u = q[front++];
if (front > Max)
front = 0;
inq[u] = 0;
for (int i = 0; i < M; i++)
if ((u & s[1][i]) == s[1][i] && ((~u) & s[0][i]) == s[0][i]){
int v = u;
v |= t[1][i];
v &= (~t[0][i]);
if (d[u]+w[i] < d[v]){
d[v] = d[u] + w[i];
if (!inq[v]){
q[rear++] = v;
if (rear > Max)
rear = 0;
inq[v] = 1;
}
}
}
}
if (d[0] == INF)
puts("Bugs cannot be fixed.");
else printf("Fastest sequence takes %d seconds.\n",d[0]);
}
int main(){
int t = 0;
while (init()){
printf("Product %d\n",++t);
SPFA();
printf("\n");
}
return 0;
}