洛谷P2622 关灯问题II (二进制枚举+bfs

题目描述

现有n盏灯,以及m个按钮。每个按钮可以同时控制这n盏灯——按下了第i个按钮,对于所有的灯都有一个效果。按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时候,把它关上,否则不管;如果为-1的话,如果这盏灯是关的,那么把它打开,否则也不管;如果是0,无论这灯是否开,都不管。

现在这些灯都是开的,给出所有开关对所有灯的控制效果,求问最少要按几下按钮才能全部关掉。

输入格式

前两行两个数,n m

接下来m行,每行n个数,a[i][j]表示第i个开关对第j个灯的效果。

输出格式

一个整数,表示最少按按钮次数。如果没有任何办法使其全部关闭,输出-1

输入输出样例

输入 #1
3
2
1 0 1
-1 1 0
输出 #1
2

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 150;
 4 bool vis[N];
 5 int mmp[N][N],m,n,num;
 6 struct qwq{
 7     int now,step;
 8 };
 9 void bfs(int n ){
10     queue<qwq>Q;qwq f;
11     f.now = n;f.step = 0;Q.push(f);
12     while(!Q.empty()){
13         qwq orz = Q.front();Q.pop();
14         for(int i = 0;i < m;++i){
15             int now = orz.now;
16             for(int j = 0;j <num;++j){
17                 if(mmp[i][j]==1){
18                     if(now&(1<<j))now = now^(1<<j);
19                 }
20                 else if(mmp[i][j]==-1){
21                     now = ((1<<j)|now);
22                 }
23             }
24             f.now = now,f.step = orz.step+1;
25             if(vis[now])continue;
26             if(f.now == 0){
27                 vis[0] = true;
28                 cout<<f.step<<endl;
29                 return ;
30             }
31             Q.push(f);vis[now] = true;
32         }
33     }
34 }
35 int main()
36 {
37     cin>>n>>m;num = n;
38     for(int i = 0;i < m;++i)
39         for(int j = 0;j < n;++j)
40             cin>>mmp[i][j] ;
41     bfs((1<<n)-1);
42     if(!vis[0])cout<<"-1"<<endl;
43     return 0;
44 }

猜你喜欢

转载自www.cnblogs.com/h404nofound/p/11826372.html
今日推荐