UVA 658 It's not a Bug, it's a Feature! (最短路)

题意:假定有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);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值