658 - It's not a Bug, it's a Feature!

来源:互联网 发布:网络测速原理 编辑:程序博客网 时间:2024/05/08 22:20

//这题使用spfa的变型,也算是类似于隐式图搜索吧

//题目的关键是如何把"状态"清楚容易的表示出来,于是想到2进制,这里有个小技巧就是用 a 和 b 分别表示 - 和 + 的状态,而0则忽略

//运用正确的位运算 既能忽略0的影响

#include <iostream>
#include <string>
#include <cstdio>
#include <queue>
#include <vector>
#include <queue>
#include <utility>
#include <memory.h>

using namespace std;
typedef pair<int,int> pii;
const int MAX=105;
struct Edge{
    int a,b,cost,
        toMinus,toPlus;
};
bool findFlag,done[MAX*MAX*MAX];
int n,m,totalCost;
string s1,s2;
Edge e[MAX];
priority_queue<pii,vector<pii>,greater<pii> > q;

void read(){
    for(int i=0;i<m;i++){
        cin>>e[i].cost>>s1>>s2;
        //cout<<s1<<" "<<s2<<endl;
        e[i].a=e[i].b=0;//a表示'-',b表示'+'
        for(int j=0;j<(int)s1.size();j++){
            if(s1[j]=='-')
                e[i].a=e[i].a|(1<<j);
            else if(s1[j]=='+')
                e[i].b=e[i].b|(1<<j);
        }
        //cout<<e[i].a<<" "<<e[i].b<<endl;
        e[i].toMinus=e[i].toPlus=0;
        for(int j=0;j<(int)s2.size();j++){
            if(s2[j]=='-')
                e[i].toMinus=e[i].toMinus|(1<<j);
            else if(s2[j]=='+')
                e[i].toPlus=e[i].toPlus|(1<<j);
        }
        //cout<<e[i].toMinus<<" "<<e[i].toPlus<<endl<<endl;
    }
}
void dijkstraVariant(){
    int num,t,time,a,b;
    pii u;
    memset(done,false,sizeof(done));
    while(!q.empty()) q.pop();
    q.push(make_pair(0,(1<<n)-1));
    while(!q.empty()){
        u=q.top();q.pop();
        num=u.second;//每一个确定的状态用二进制01表示,其中1表示正
        if(done[num])//second 代表数,first代表消耗时间
            continue;
        if(num==0){
            findFlag=1;
            totalCost=u.first;
            break;
        }
        done[num]=true;
        time=u.first;
        for(int i=0;i<m;i++){
            a=e[i].a;
            b=e[i].b;
            if((((~num)&a)==a)&&((num&b)==b)){
                t=num;
                t=t&(~e[i].toMinus);//将num的-号位设置为0;
                t=t|e[i].toPlus;//将num的+号位设置为0
                q.push(make_pair(time+e[i].cost,t));
            }
        }
    }
}
int main()
{
    freopen("i.txt","r",stdin);
    int caseNumber=1;
    while(cin>>n>>m){
        if(!n&&!m)
            break;
        read();
        findFlag=0;
        dijkstraVariant();
        cout<<"Product "<<caseNumber++<<endl;
        if(findFlag)
            cout<<"Fastest sequence takes "<<totalCost
                <<" seconds."<<endl;
        else
            cout<<"Bugs cannot be fixed."<<endl;
        cout<<endl;
    }
    return 0;
}