spfa 二进制 It's not a BUG, it's a feature

原题: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;
}