您的位置:首页 > 理论基础 > 数据结构算法

农夫过河问题(图的邻接矩阵)

2015-11-12 22:11 519 查看
/*******************************************************************************
*农夫过河问题(图的邻接矩阵存储,深度优先遍历):								   *
*一个农夫带着一只羊、一只狼、和一颗白菜过河(左岸->右岸);					   *
*河边只有一条船,由于船太小,只能装下农夫和他的一样东西;					   *
*在无人看管的情况下,狼要吃羊,羊要吃菜;									   *
*请问农夫如何才能使三样东西平安过河。										   *
*******************************************************************************/
#include<iostream>
#define MaxVertexNum  30
using namespace std;

typedef struct{			/*顶点*/
int farmer;
int wolf;
int sheep;
int vegetable;
}VertexType;

typedef struct{			/*邻接矩阵*/
VertexType vertexs[MaxVertexNum];
int edges[MaxVertexNum][MaxVertexNum];
int vertexNum;//顶点个数
}MGraph;

int locate(MGraph * G,int F,int W,int S,int V);	/*查找顶点(F,W,S,V)在顶点向量中的位置*/
int is_safe(int F,int W,int S,int V);			/*判断目前的顶点(F,W,S,V)是否安全*/
int is_connected(MGraph * G,int i,int j);		/*判断状态i与状态j之间是否可转换*/
void CreateG(MGraph * G);						/*生成所有安全的图的顶点*/
void print_path(MGraph * G,int u,int v);		/*输出从u到v的简单路径,即顶点序列不重复出现的路径*/
void DFS_path(MGraph * G,int u,int v);			/*深度优先搜索从u到v的简单路径*/
void DFStraverse(MGraph * G,int i,int j);		/*深度优先遍历*/

bool visited[MaxVertexNum];	//设置访问状态:false未访问
int path[MaxVertexNum];		//保存DFS搜索到的路径

int main(){
MGraph G;
CreateG(&G);//创建图

cout<<"输出满足基本条件的情况:";
for(int k=0;k<G.vertexNum;k++)
cout<<"\n("<<G.vertexs[k].farmer<<","<<G.vertexs[k].wolf<<","<<G.vertexs[k].sheep<<","<<G.vertexs[k].vegetable<<")";

int i=locate(&G,0,0,0,0);//起点状态
int j=locate(&G,1,1,1,1);//终点状态

cout<<"\n\n农夫过河问题的深度优先遍历:";
DFStraverse(&G,i,j);

return 0;
}

/*查找顶点(F,W,S,V)在顶点向量中的位置*/
int locate(MGraph * G,int F,int W,int S,int V){
for(int i=0;i<G->vertexNum;i++){
if(G->vertexs[i].farmer==F && G->vertexs[i].wolf==W && G->vertexs[i].sheep==S && G->vertexs[i].vegetable==V)
return i;//返回当前顶点的位置
}
return -1;//没有找到此点
}

/*判断目前的顶点(F,W,S,V)是否安全*/
int is_safe(int F,int W,int S,int V){
//当农夫与羊不在一起时,狼与羊或羊与白菜在一起是不安全的
if((F!=S) && (W==S || S==V))
return 0;
else
return 1;
}

/*判断状态i与状态j之间是否可转换*/
int is_connected(MGraph * G,int i,int j){
int k=0;
if(G->vertexs[i].wolf != G->vertexs[j].wolf)
k++;
if(G->vertexs[i].sheep != G->vertexs[j].sheep)
k++;
if(G->vertexs[i].vegetable != G->vertexs[j].vegetable)
k++;
//农夫每次只能带一样东西过河
if(G->vertexs[i].farmer != G->vertexs[j].farmer && k<=1)
return 1;
else
return 0;
}

/*生成所有安全的图的顶点*/
void CreateG(MGraph * G){
int i,j,F,W,S,V;
i=0;
for(F=0;F<=1;F++){
for(W=0;W<=1;W++){
for(S=0;S<=1;S++){
for(V=0;V<=1;V++){
if(is_safe(F,W,S,V)){
G->vertexs[i].farmer=F;
G->vertexs[i].wolf=W;
G->vertexs[i].sheep=S;
G->vertexs[i].vegetable=V;
i++;
}
}
}
}
}
G->vertexNum=i;//安全的顶点个数
for(i=0;i<G->vertexNum;i++){
for(j=0;j<G->vertexNum;j++){
if(is_connected(G,i,j)){
G->edges[i][j]=1;
G->edges[j][i]=1;
}else{
G->edges[i][j]=0;
G->edges[j][i]=0;
}
}
}
}

/*输出从u到v的简单路径,即顶点序列不重复出现的路径*/
void print_path(MGraph * G,int u,int v){
int k=u;
while(k != v){
cout<<"\n("<<G->vertexs[k].farmer<<","<<G->vertexs[k].wolf<<","<<G->vertexs[k].sheep<<","<<G->vertexs[k].vegetable<<")";
k=path[k];
}
cout<<"\n("<<G->vertexs[k].farmer<<","<<G->vertexs[k].wolf<<","<<G->vertexs[k].sheep<<","<<G->vertexs[k].vegetable<<")";
}

/*深度优先搜索从u到v的简单路径*/
void DFS_path(MGraph * G,int u,int v){
visited[u]=true;
for(int j=0;j<G->vertexNum;j++){
if(G->edges[u][j] && !visited[j] && !visited[v]){
path[u]=j;
DFS_path(G,j,v);
}
}
}

/*深度优先遍历*/
void DFStraverse(MGraph * G,int i,int j){
for(int t=0;t<G->vertexNum;t++)
visited[t]=false;
DFS_path(G,i,j);
if(visited[j])
print_path(G,i,j);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  代码 数据结构 算法