求教这里的dfs算法该怎么理解?

Henryinferno 2013-07-17 06:39:07
poj2965:The Pilots Brothers' refrigerator
Time Limit: 1000MS
Memory Limit: 65536K
Total Submissions: 10158
Accepted: 3707
Special Judge

Description
The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator.
There are 16 handles on the refrigerator door. Every handle can be in one of two states: open or closed. The refrigerator is open only when all handles are open. The handles are represented as a matrix 4х4. You can change the state of a handle in any location [i, j] (1 ≤ i, j ≤ 4). However, this also changes states of all handles in row i and all handles in column j.
The task is to determine the minimum number of handle switching necessary to open the refrigerator.
Input
The input contains four lines. Each of the four lines contains four characters describing the initial state of appropriate handles. A symbol “+” means that the handle is in closed state, whereas the symbol “−” means “open”. At least one of the handles is initially closed.
Output
The first line of the input contains N – the minimum number of switching. The rest N lines describe switching sequence. Each of the lines contains a row number and a column number of the matrix separated by one or more spaces. If there are several solutions, you may give any one of them.
Sample Input
-+--
----
----
-+--
Sample Output
6
1 1
1 3
1 4
4 1
4 3
4 4
Source
Northeastern Europe 2004, Western Subregion

题目大意:一个冰箱有16个开关,呈方形分布(4*4矩阵),“+”表示关闭,“-”表示开着,当所有的开关为“+”时冰箱才能打开。当去翻转一个开关时,在该开关所在列和行的所有开关都要翻转,即开变关,关变开。问至少需要多少次才能打开冰箱。

网上看到的一种用DFS方法的代码:
#include<iostream>
using namespace std;

bool board[16];
int is[16];
int js[16];
bool check(){
for(int i=0;i<16;i++){
if(board[i]!=1)
return false;
}
return true;
}
void init(){
char a;
for(int i=0;i<16;i++){
cin>>a;
if(a=='+'){
board[i]=0;
}else{
board[i]=1;
}
}

}
void flip(int pos){
int i=pos/4;
int j=pos%4;
board[pos]=!board[pos];
for(int m=0;m<4;m++){
board[i*4+m]=!board[i*4+m];
board[(m)*4+j]=!board[(m)*4+j];
}
}
bool dfs(int pos,int step){
if(check()){
cout<<step<<endl;
for(int i=0;i<step;i++){
cout<<is[i]<<" "<<js[i]<<endl;
}
return true;
}
if(pos>=16){
return false;
}
if(dfs(pos+1,step))//这里是什么意思?为什么这里递归step不要加1
return true;
flip(pos);
is[step]=pos/4+1;//这里记录下了什么?
js[step]=pos%4+1;
if(dfs(pos+1,step+1))
return true;
flip(pos);
return false;

}
int main(){
init();
dfs(0,0);
}


小白看了很长时间不懂,我想请教一下这里dfs函数是什么意思?不能理解是如何搜索的。
一般DFS接受一个图的节点(状态),然后搜索完一个分支回溯再搜索另一个分支,直到搜索完整个图。
对于这个题目来说节点是什么?分支又是什么呢?而且每个节点是通过什么方式表示是否被访问过了呢?
...全文
398 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Henryinferno 2013-07-18
  • 打赏
  • 举报
回复
引用 6 楼 wsx199397 的回复:
[quote=引用 4 楼 FancyMouse 的回复:] [quote=引用 3 楼 wsx199397 的回复:] [quote=引用 1 楼 FancyMouse 的回复:] 节点是所有16个点。分支是该点是否做操作。这个图是个DAG所以不需要记录访问情况 >//这里是什么意思?为什么这里递归step不要加1 第一个分支情况是该点不进行操作,因此step不加1 >//这里记录下了什么? 本次操作的节点行列。因为最后需要输出。
请问向这种实际问题如何判断图是有向还是无向的?[/quote] 这里这图是你自己构造出来的。你自己构造的图你自己知道怎么回事。[/quote] 这种算法是别人写的啊,所以我才不知道这图他当时怎么构造出来的。。[/quote] 也就是我想知道您是怎么看出来这个问题可以抽象成一个DAG图的。
Henryinferno 2013-07-18
  • 打赏
  • 举报
回复
引用 5 楼 ak47_wz 的回复:
[quote=引用 2 楼 u010936098 的回复:] “问至少需要多少次才能打开冰箱。”那就是要找出最小次数,怎么会用DFS?应该用BFS才对啊。
DFS,BFS应该都能做的.[/quote]嗯,我也这么认为
Henryinferno 2013-07-18
  • 打赏
  • 举报
回复
引用 4 楼 FancyMouse 的回复:
[quote=引用 3 楼 wsx199397 的回复:] [quote=引用 1 楼 FancyMouse 的回复:] 节点是所有16个点。分支是该点是否做操作。这个图是个DAG所以不需要记录访问情况 >//这里是什么意思?为什么这里递归step不要加1 第一个分支情况是该点不进行操作,因此step不加1 >//这里记录下了什么? 本次操作的节点行列。因为最后需要输出。
请问向这种实际问题如何判断图是有向还是无向的?[/quote] 这里这图是你自己构造出来的。你自己构造的图你自己知道怎么回事。[/quote] 这种算法是别人写的啊,所以我才不知道这图他当时怎么构造出来的。。
水平不流 2013-07-18
  • 打赏
  • 举报
回复
引用 2 楼 u010936098 的回复:
“问至少需要多少次才能打开冰箱。”那就是要找出最小次数,怎么会用DFS?应该用BFS才对啊。
DFS,BFS应该都能做的.
FancyMouse 2013-07-18
  • 打赏
  • 举报
回复
引用 3 楼 wsx199397 的回复:
[quote=引用 1 楼 FancyMouse 的回复:] 节点是所有16个点。分支是该点是否做操作。这个图是个DAG所以不需要记录访问情况 >//这里是什么意思?为什么这里递归step不要加1 第一个分支情况是该点不进行操作,因此step不加1 >//这里记录下了什么? 本次操作的节点行列。因为最后需要输出。
请问向这种实际问题如何判断图是有向还是无向的?[/quote] 这里这图是你自己构造出来的。你自己构造的图你自己知道怎么回事。
Henryinferno 2013-07-18
  • 打赏
  • 举报
回复
引用 1 楼 FancyMouse 的回复:
节点是所有16个点。分支是该点是否做操作。这个图是个DAG所以不需要记录访问情况 >//这里是什么意思?为什么这里递归step不要加1 第一个分支情况是该点不进行操作,因此step不加1 >//这里记录下了什么? 本次操作的节点行列。因为最后需要输出。
请问向这种实际问题如何判断图是有向还是无向的?
橡木疙瘩 2013-07-18
  • 打赏
  • 举报
回复
“问至少需要多少次才能打开冰箱。”那就是要找出最小次数,怎么会用DFS?应该用BFS才对啊。
FancyMouse 2013-07-18
  • 打赏
  • 举报
回复
节点是所有16个点。分支是该点是否做操作。这个图是个DAG所以不需要记录访问情况 >//这里是什么意思?为什么这里递归step不要加1 第一个分支情况是该点不进行操作,因此step不加1 >//这里记录下了什么? 本次操作的节点行列。因为最后需要输出。

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧