题意:假定有n个潜在的bug和m个补丁,每个补丁用长为n的字符串表示。首先输入bug数目以及补丁数目。然后就是对m个补丁的描述,共有m行。每行首先是一个整数,表明打该补丁所需要的时间。然后是两个字符串,地一个字符串是对软件的描述,只有软件处于该状态下才能打该补丁该字符串的每一个位置代表bug状态(-代表该位置没bug,+代表该位置有bug,0表示该位置无论有没有bug都可打补丁)。然后第二个字符串是对打上补丁后软件状态的描述-代表该位置上的bug已经被修复,+表示该位置又引入了一个新的bug, 0表示该位置跟原来状态一样)。要求用最少时间完成对软件的修复,即将所有位置全都置为0.
分析:根据状态确定是否转移求最短路。通过这题可以看出,最短路的根本还是动态规划。(误把j写成i找了好久。。。)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define FRER() freopen("in.txt","r",stdin)
#define FREW() freopen("out.txt","w",stdout)
#define go int T;cin>>T;for(int kase=1;kase<=T;kase++)
#define debug cout<<"****************"<<endl
#define mod 1000000007
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template <class T> T gcd(T a,T b){return !b?a:gcd(b,a%b);}
const int N = (1<<20) + 7 , M = 107 , inf = 0x3f3f3f3f;
string s1[M],s2[M];
int d[N],c[M],vis[N],n,m;
priority_queue<pii,vector<pii>,greater<pii> >q;
bool read(){
cin >> n >> m;
if(!n && !m) return false;
for(int i = 0 ; i < m ; i ++) cin >> c[i] >> s1[i] >> s2[i];
return true;
}
bool ok(int st,int i){
for(int j = 0 ; j < n ; j++){
if(s1[i][j]=='+'){ if(!(st&(1<<j))) return false;}
if(s1[i][j]=='-'){ if(st&(1<<j)) return false;}
}
return true;
}
void change(int& st,int i){
for(int j = 0 ; j < n ; j++){
if(s2[i][j] == '+') st |= (1<<j);
if(s2[i][j] == '-') st &= ~(1<<j);
}
}
int Dijstra(){
while(!q.empty()) q.pop();
memset(d, inf, sizeof(d));
memset(vis, 0, sizeof(vis));
int u = (1<<n) - 1;
d[u] = 0;
q.push(pii(d[u],u));
while(!q.empty()){
pii now = q.top();q.pop();
u = now.second;
if(u==0) return d[u];
if(vis[u]) continue;
vis[u] = 1;
for(int i = 0 ; i < m ; i++){
if(ok(u , i)){
int v = u;
change(v , i);
if(d[u] + c[i] < d[v]){
d[v] = d[u] + c[i];
q.push(pii(d[v],v));
}
}
}
}
return -1;
}
int main(){
FRER();
FREW();
int k = 1;
while(read()){
int ans = Dijstra();
printf("Product %d\n",k++);
ans == -1 ? printf("Bugs cannot be fixed.\n\n") : printf("Fastest sequence takes %d seconds.\n\n",ans);
}
}