实验6:图及其遍历

第1关:迷宫问题

任务描述

密密被困在一个迷宫里,迷宫有n个路口,编号为1-n。密密现在站在第一个路口,出口编号为m。先给出每个路口通向何处,问密密能否逃出迷宫。

编程要求

输入

多组数据,每组数据n+2行。第一行为一个正整数n代表路口的个数,之后n行,这n行中的第i行为第i个路口的向左路口、向前路口、向右路口。最后一行为一个正整数m代表迷宫的终点。当n=0时输入结束。

输出

每组数据输出一行,若密密能走出迷宫,输出“YES”,否则输出“NO”。

测试说明

平台会对你编写的代码进行测试:

测试输入:

6

0 2 0

3 5 6

0 0 4

0 0 0

0 0 0

7 0 0

7

3

2 0 0

0 0 0

0 0 0

3

0

预期输出:

YES

NO

上答案:
 

#include <iostream>
using namespace std;
int m,n;//m:出口编号  n:入口
int tag;//输出标记
int DFS(int k,int (*a)[3])
{//深度搜索第k层,k:当前路口
/**************begin************/
 if(k==m)
{
    tag=1;
    return 1;
}
for(int i=0;i<3;i++)
{
    if(a[k][i]!=0&&a[k][i]!=k)
    {
        if(DFS(a[k][i],a)==1)
        {
        tag=1;
        return 1;
         }
    }
}
return 0;

    /**************end************/
}
int main()
{
	while(cin>>n)
	{
	if(n==0)break;
	int i,j;
	tag=0;
	int a[n+1][3];//迷宫
	for(i=1;i<=n;i++)
		for(j=0;j<3;j++)
			cin>> a[i][j];
	cin>>m;
	DFS(1,a);//从第一层开始搜索
	if(tag==1)
		cout<<"YES"<<endl;
	else if(tag==0)
		cout<<"NO"<<endl;
	}
	return 0;
}

第2关:基于邻接表的深度优先遍历

任务描述

一个连通图采用邻接表作为存储结构。设计一个算法,实现从顶点v出发的深度优先遍历的非递归过程。

编程要求

输入

多组数据,每组m+2数据行。第一行有两个数字n和m,代表有n个顶点和m条边。顶点编号为1到n。第二行到第m+1行每行有两个整数h和k,代表边依附的两个顶点。第m+2行有一个整数d,代表从d开始遍历。当n和m都等于0时,输入结束。

输出

每组数据输出一行,为深度优先搜索的遍历结果。每两个数字之间用空格隔开。

测试说明

平台会对你编写的代码进行测试:

测试输入:

3 2

1 2

1 3

1

2 1

1 2

2 0

0

预期输出:

1 3 2

2 1

上答案:
 

#include<iostream>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXSIZE 100
using namespace std;
typedef struct ArcNode
{//边结点
	int data;
	struct ArcNode *nextarc; //链域:指向下一条边的指针
}ArcNode;
typedef struct VNode
{//顶点信息
	int data;
	ArcNode *firstarc;  //链域:指向第一条依附该顶点的边的指针
}VNode,AdjList[MAXSIZE];    //AdjList表示邻接表类型
typedef struct
{//邻接表
	AdjList vertices;
	int vexnum,arcnum;    //图的当前顶点数和边数
}ALGraph;
typedef struct
{//顺序栈
	int *base;          //栈底指针
	int *top;           //栈顶指针
	int stacksize;      //栈可用的最大容量
}SqStack;
void InitStack(SqStack &S)
{//顺序栈的初始化
	S.base=new int[MAXSIZE];   //动态分配一个最大容量MAXSIZE的数组空间
	S.top=S.base;           //top初始为base,空栈
	S.stacksize=MAXSIZE;
}
void Push(SqStack &S,int e)
{//入栈操作
	if(S.top-S.base==S.stacksize)   //栈满
		return;
	*S.top=e;    //元素e压入栈顶
	S.top++;        //栈顶指针加1
}
void Pop(SqStack &S,int &e)
{//出栈操作
	if(S.base==S.top)    //栈空
		return;
	S.top--;        //栈顶指针减1
	e=*S.top;        //将栈顶元素赋给e
}
bool StackEmpty(SqStack S)
{//判空操作
	if(S.base==S.top)    //栈空返回true
		return true;
	return false;
}
bool visited[MAXSIZE];    //访问标志数组,初始为false
int CreateUDG(ALGraph &G,int vexnum,int arcnum)
{//采用邻接表表示法,创建无向图G
    G.vexnum=vexnum;     //输入总顶点数
	G.arcnum=arcnum;     //输入总边数
	if(G.vexnum>MAXSIZE) return ERROR;  //超出最大顶点数则结束函数
	int i,h,k;
	for(i=1;i<=G.vexnum;i++)   //构造表头结点表
    {
        G.vertices[i].data=i;
        visited[i]=false;
        G.vertices[i].firstarc=NULL;
    }
    ArcNode *p1,*p2;
    for(i=0;i<G.arcnum;i++)   //输入各边,头插法构造邻接表
    {
        cin>>h>>k;
        p1=new ArcNode;
        p1->data=k;
        p1->nextarc=G.vertices[h].firstarc;
        G.vertices[h].firstarc=p1;
        p2=new ArcNode;
        p2->data=h;
        p2->nextarc=G.vertices[k].firstarc;
        G.vertices[k].firstarc=p2;
    }
    return OK;
}
void DFS(ALGraph G,int v,SqStack S)
{//从第v个顶点出发非递归实现深度优先遍历图G
/**************begin************/
   Push(S,v);//入栈
    visited[v]=true;//标记v已经被访问
    cout<<v<<" ";
    while(!StackEmpty(S))//栈不空时循环
    {
        int w=S.top[-1];//取栈顶元素w
        ArcNode *p=G.vertices[w].firstarc;
        while(p!=NULL)
        {
            if(!visited[p->data])//若p->data未被访问
            {
                Push(S,p->data);//将其入栈
                visited[p->data]=true;
                cout<<p->data;
                if(p->nextarc!=NULL)
                {
                    cout<<" ";
                }
                break;
            }
            p=p->nextarc;
        }
        if(p==NULL)
        {
            Pop(S,w);//若w的所有邻接点都被访问完了,弹出栈
        }
    } 
   // cout<<endl;
   
    /**************end************/
}
int main()
{
	int n,m;
	while(cin>>n>>m)
	{
		if(n==0&&m==0) break;
		ALGraph G;
		SqStack S;
        InitStack(S);
		CreateUDG(G,n,m);   //创建无向图G
		int d;             //从d开始遍历
		cin>>d;
		DFS(G,d,S); 
        cout<<endl;
        //基于邻接表的深度优先遍历
	}
   
	return 0;
}

第3关:基于邻接表的长度为k的简单路径的求解

任务描述

一个连通图采用邻接表作为存储结构。设计一个算法,判断无向图中任意给定的两点是否存在一条长度为k的简单路径。

编程要求

输入

多组数据,每组m+3数据行。第一行有两个数字n,m和k,代表有n个顶点,m条边和长度k。第二行有n个字符,代表n个顶点的编号。第三行到第m+2行每行有两个字符h和p,代表边依附的两个顶点。每条边的长度为1。第m+3行有两个字符d和f,代表需要判断的两个字符。

输出

每组数据输出一行。若存在路径输出“YES”,反之输出“NO”。

测试说明

平台会对你编写的代码进行测试:

测试输入:

3 2 2

abc

ab

bc

ac

4 2 5

bcsw

bs

sw

bw

0 0 0

预期输出:

YES

NO

上答案:

#include<iostream>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MVNum 100     //最大顶点数
using namespace std;
typedef struct ArcNode
{//边结点
	int adjvex;                //邻接点域:该边所指向的顶点的位置
	char data;                  //数据域:存储和边相关的信息
	struct ArcNode* nextarc;   //链域:指向下一条边的指针
}ArcNode;
typedef struct VNode
{//顶点信息
	char data;              //顶点结点的数据域
	ArcNode *firstarc;     //链域:指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNum];     //AdjList表示邻接表类型
typedef struct
{//邻接表
	AdjList vertices;
	int vexnum,arcnum;    //图的当前顶点数和边数
}ALGragh;
int Locate(char ch[],char h)
{//存在则返回h在数组中的下标,否则返回ERROR
	int i;
	for(i=0;ch[i]!='\0';i++)
	{
		if(ch[i]==h)
			return i;
	}
	return ERROR;
}
bool visited[MVNum];  //访问标记数组,已访问顶点的值记为true
bool PathLenK(ALGragh G,int pD,int pF,int k)
{//判断邻接表方式存储的有向图G的顶点pD到pF是否存在长度为k的简单路径
    if(pD==pF&&k==0) return true;     //找到了一条路径,且长度符合要求
    else if(k>0)      //从结点pD开始遍历,p为pD的边链表的第一个结点
    {
        visited[pD]=true;
        ArcNode *p;
        for(p=G.vertices[pD].firstarc;p;p=p->nextarc)
        {
            int v=p->adjvex;
            if(!visited[v])       //v从未被访问过
            {
                if(PathLenK(G,v,pF,k-1))
                    return true;      //递归继续遍历判断pD到pF,且剩余路径长度减1
            }
        }
        visited[pD]=false;//允许曾经被访问过的结点出现在另一条路径中
    }
    return false;      //没找到
}
int CreateUDG(ALGragh &G,int vexnum,int arcnum,char ch[])
{//采用邻接表表示法,创建无向图G
/**************begin************/
	//输入各点,构造表头结点表
	G.arcnum=arcnum; 
	G.vexnum=vexnum; 
	for(int i=0;i<G.vexnum;i++)
	{
		G.vertices[i].data=ch[i];
		G.vertices[i].firstarc=NULL;    //初始化没有边
	}	
	//输入各边,构造邻接表   
    for(int k=0;k<G.arcnum;k++)
    {
		char h,p;  
		cin>>h>>p;
		int i=Locate(ch,h);
		int j=Locate(ch,p);
		ArcNode *q=(ArcNode*)malloc(sizeof(ArcNode)); //向内存申请空间,生成边结点*q
		q->adjvex=j;             //邻接点编号为j
		q->nextarc=G.vertices[i].firstarc; //将*q的指针指向顶点i的边链表头结点
		G.vertices[i].firstarc=q;          //将当前的边*q置为顶点i的边链表头结点
		q=(ArcNode*)malloc(sizeof(ArcNode)); //向内存申请空间,生成边结点*q
		q->adjvex=i;             //邻接点编号为i
		q->nextarc=G.vertices[j].firstarc; //将*q的指针指向顶点j的边链表头结点
		G.vertices[j].firstarc=q;          //将当前的边*q置为顶点j的边链表头结点
	}
	return OK;

  
    
      /**************end************/
}
int main()
{
	int n,m,k;   //n个顶点,m条边和长度k
	while(cin>>n>>m>>k)
	{
		if(n==0&&m==0&&k==0) break;
		char ch[MVNum];
		cin>>ch;
		ALGragh G;
		CreateUDG(G,n,m,ch);    //创建无向图G
		char d,f;    //d和f代表需要判断的两个字符
		cin>>d>>f;
		int pd=Locate(ch,d);
		int pf=Locate(ch,f);
        if(PathLenK(G,pd,pf,k))
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
	return 0;
}

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Galaxy*★

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值