CODEVS2594 解药还是毒药 - 状态压缩+BFS

传送门

思路:我们用一个n位二进制数表示当前疾病的状态:0表示已经治愈,1表示未治愈。通过BFS遍历所有状态,对于每个状态x,我们枚举所有解药,若当前解药i能够治愈第j种疾病,就将x的第j位赋值为0;若当前解药i能够使人得第j种疾病,就将x的第j位赋值为1。注意,别忘了对状态判重!若第一次所有疾病都被治愈,即x=0时,此时的解为最优解。若BFS结束后x仍不为0,那么这个人就gg了。

AC Code:

/*
状态判重啊啊!!! 
*/

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=10+2,M=100+2;
int n,m;
int a[M][N];
int ans=(1<<30);
struct node{
    int x,ud;
};
queue<node>q;
bool vis[1<<N];
bool bfs(){
    while(q.size()) q.pop();
    q.push((node){(1<<n)-1,0});
    while(q.size()){
        node p=q.front();q.pop();
        int x=p.x,ud=p.ud;
        if(x==0) {
            ans=min(ans,ud);return 1;    
        }
        for(int i=0;i<m;i++){
            int tmp=x;
            for(int j=0;j<n;j++){    
                if(a[i][j]==1) x=x&(~(1<<j));
                else if(a[i][j]==-1) x=x|(1<<j);
            }
            if(!vis[x]){
                q.push((node){x,ud+1});
                vis[x]=1;
            }
            x=tmp;
        }
    }
    return 0;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++) 
        for(int j=0;j<n;j++) scanf("%d",&a[i][j]);
    if(bfs()) printf("%d",ans);
    else printf("The patient will be dead.");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Loi-Brilliant/p/9425291.html