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; }