uva658 dijkstra+状态压缩

题目大意:

假定有n个潜在的bug和m个补丁,每个补丁用长为n的字符串表示。首先输入bug数目以及补丁数目。然后就是对m 个补丁的描述,共有m行。每行首先是一个整数,表明打该补丁所需要的时间。然后是两个字符串,地一个字符串 是对软件的描述,只有软件处于该状态下才能打该补丁该字符串的每一个位置代表bug状态(-代表该位置没bug,+代 表该位置有bug,0表示该位置无论有没有bug都可打补丁)。然后第二个字符串是对打上补丁后软件状态的描述 -代表该位置上的bug已经被修复,+表示该位置又引入了一个新的bug, 0表示该位置跟原来状态一样)。要求用最少 时间完成对软件的修复,即将所有位置全都置为0.

基本思路:

状态压缩一下转化为最短路来处理

代码如下:

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>

using namespace std;

typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 1000000000+10;
int n,m,t[110],d[1<<20],vis[1<<20];
char before[110][25],after[110][25];

struct Node{
    int bug,dist;
    bool operator<(const Node& rhs)const{
        return dist>rhs.dist;
    }
};

int dijkstra(){
    for(int i=0;i<(1<<n);i++){
        d[i]=inf;
        vis[i]=0;
    }
    priority_queue<Node>q;
    Node start;
    start.bug=(1<<n)-1;
    start.dist=0;
    q.push(start);
    d[start.bug]=0;
    while(!q.empty()){
        Node x=q.top();q.pop();
        if(x.bug==0) return x.dist;
        if(vis[x.bug]) continue;
        vis[x.bug]=1;
        for(int i=0;i<m;i++){
            bool pat=true;
            for(int j=0;j<n;j++){
                if(before[i][j]=='-'&&(x.bug&(1<<j))){
                    pat=false;
                    break;
                }
                if(before[i][j]=='+'&&!(x.bug&(1<<j))){
                    pat=false;
                    break;
                }
            }
            if(!pat) continue;
            Node next;
            next.bug=x.bug;
            next.dist=x.dist+t[i];
            for(int j=0;j<n;j++){
                if(after[i][j]=='-') next.bug&=~(1<<j);
                if(after[i][j]=='+') next.bug|=(1<<j);
            }
            int &D=d[next.bug];
            if(next.dist<D){
                D=next.dist;
                q.push(next);
            }
        }
    }
    return -1;
}
int main(){
    int cas=0;
    while(scanf("%d%d",&n,&m)==2&&n){
        for(int i=0;i<m;i++){
            scanf("%d%s%s",&t[i],&before[i],&after[i]);
        }
        int ans=dijkstra();
        printf("Product %d\n",++cas);
        if(ans<0){
            printf("Bugs cannot be fixed.\n\n");
        }else{
            printf("Fastest sequence takes %d seconds.\n\n",ans);
        }
    }
    return 0;
}

  

posted @ 2018-02-14 17:18  愿~得偿所愿,不负时光  阅读(93)  评论(0编辑  收藏  举报