http://www.4399.com/flash/77287_2.htm
这是最基本的dfs方法 遍历所有情况
dfs过程中 只需要满足几个基本条件就可以
1. 传教士和野人数量都要在0~~3之间
2.传教士的数量一定要大于等于野人的数量
3.不可以走重复路线,避免构成循环,不可以回到起点的状态.
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
//岸的状态
typedef struct
{
int wild_man;
int church_man;
}RiverSide;
//船的状态
typedef struct
{
int wild_man;
int church_man;
}Boat;
//问题的目的是 将a岸的所有人运送到b岸 所以初始状态始 船在a岸
enum SIDE{ atA, atB };
//问题的状态
typedef struct ques
{
RiverSide rA;
RiverSide rB;
SIDE Side;//该时刻 船所在的位置
Boat boat;//船的状态
struct ques *next;
struct ques *pre;
}QUESTION;
QUESTION *start;
int SUM=0, sum=0;
Boat change[5] = { { 1, 0 }, { 0, 1 }, { 2, 0 }, { 0, 2 }, { 1, 1 } };
int state[100] = { 0 };
int Get_s(QUESTION *s)
{
return s->Side * 16 + s->rA.church_man * 4 + s->rA.wild_man;
}
void ERROR(int i)
{
if (i == 1)
{
cout << "fail malloc !" << endl; exit(1);
}
}
void output_QUESTION(QUESTION *p)
{
//船从*岸滑向~*岸(*牧师,*野人),此时a岸状态(*牧师,*野人),b岸状态(*牧师,*野人)
++sum;
cout << sum << ".";
if (p->Side == atA)
cout << "B--->A(" << p->boat.church_man << "牧师," << p->boat.wild_man << "野人),";
else// p->side==atB
cout << "A--->B(" << p->boat.church_man << "牧师," << p->boat.wild_man << "野人),";
cout << "此时a岸状态(" << p->rA.church_man << "牧师," << p->rA.wild_man << "野人),b岸状态(" << p->rB.church_man << "牧师," << p->rB.wild_man << "野人)" << endl;
}
void output_route(QUESTION *t)
{
++SUM;
cout << "\n\n第"<<SUM<<"种方法:"<< endl;
sum = 0;
cout << "start pos:a岸状态(3牧师,3野人),b岸状态(0牧师,0野人)" << endl;
t = t->next;
while (t)
{
output_QUESTION(t);
t = t->next;
}
cout << "let it go !~~~" << endl;
}
//for success
void success()
{
output_route(start);
}
/*
dfs met:
1.任意时刻 :野人和 牧师 的 数量都要介于0~~3 牧师的数量要多余野人的数量
2.避免死循环 : 不和上一步走相同的路
*/
bool is_correct(QUESTION *t)
{
//return (t->rA.church_man >= 0 && t->rA.church_man <= 3 && t->rA.wild_man >= 0 && t->rA.wild_man <= 3) && !state[Get_s(t)] && (t->rA.church_man==0 || (t->rA.church_man>=t->rA.wild_man)) &&( t->rB.church_man==0 ||( t->rB.church_man>=t->rB.wild_man ));
return (t->rA.church_man >= 0 && t->rA.church_man <= 3 && t->rA.wild_man >= 0 && t->rA.wild_man <= 3) && !(t->rA.church_man==3 && t->rA.wild_man==3) && (t->rA.church_man == 0 || (t->rA.church_man >= t->rA.wild_man)) && (t->rB.church_man == 0 || (t->rB.church_man >= t->rB.wild_man));
}
void dfs(QUESTION *c)
{
QUESTION *p;
//for success
if (c->rB.church_man == 3 && c->rB.wild_man == 3)
{
success();
return;
}
//if (c->rA.church_man == 3 && c->rA.wild_man == 3 && !(c->boat.church_man == 0 && c->boat.wild_man == 0)) return;
if (c->Side == atA)//
{//此时船从a(c点)走向b 新状态为船在b岸的状态(p点)
for (int i = 0; i < 5; i++)
{
if (change[i].church_man == c->boat.church_man && change[i].wild_man == c->boat.wild_man)continue;
p = (QUESTION *)malloc(sizeof(QUESTION));
if (!p) { ERROR(1); }
//for ra
p->rA.church_man = c->rA.church_man - change[i].church_man;
p->rA.wild_man = c->rA.wild_man - change[i].wild_man;
//for rb
p->rB.church_man = c->rB.church_man + change[i].church_man;
p->rB.wild_man = c->rB.wild_man + change[i].wild_man;
//for side
p->Side = atB;
//for change
p->boat.church_man = change[i].church_man;
p->boat.wild_man = change[i].wild_man;
c->next = p;
p->pre = c;
p->next = NULL;
if (is_correct(p))
{
//output_QUESTION(p);
//state[Get_s(p)] = 1;
dfs(p);
}
free(p);
c->next = NULL;
}
//cout << "返回上一个节点" << endl << endl;
}
else // c->Side=atB //boat from b to a
{
for (int i = 0; i<5; i++)
{
if (change[i].church_man == c->boat.church_man && change[i].wild_man == c->boat.wild_man)continue;
p = (QUESTION *)malloc(sizeof(QUESTION));
if (!p) { ERROR(1); }
//for ra
p->rA.church_man = c->rA.church_man + change[i].church_man;
p->rA.wild_man = c->rA.wild_man + change[i].wild_man;
//for rb
p->rB.church_man = c->rB.church_man - change[i].church_man;
p->rB.wild_man = c->rB.wild_man - change[i].wild_man;
//for side
p->Side = atA;
//for change
p->boat.church_man = change[i].church_man;
p->boat.wild_man = change[i].wild_man;
c->next = p;
p->pre = c;
p->next = NULL;
if (is_correct(p))
{
//output_QUESTION(p);
//state[Get_s(p)] = 1;
dfs(p);
}
free(p);
c->next = NULL;
}
//cout << "返回上一个节点" << endl << endl;
}
}
void solve()
{
dfs(start);
}
int main()
{
//for init start
start = (QUESTION *)malloc(sizeof(QUESTION));
if (!start) { ERROR(1); }
start->rA.church_man = 3;
start->rA.wild_man = 3;
start->rB.church_man = 0;
start->rB.wild_man = 0;
start->Side = atA;
start->boat.church_man = 0;
start->boat.wild_man = 0;
start->next = NULL;
start->pre = NULL;
//end for init
state[Get_s(start)] = 1;
//output_QUESTION(start);
solve();
return 0;
}