第六章学习小结
第六章的大致学习框架如下:
其中,我们主要学习了图的存储结构,图的遍历,了解了图的应用里各个算法是如何实施的。
在图的存储结构中,在定义方面和之前学习的有点不一样,特别是邻接表表示法。我们要根据题目来判断应该结构体里面写什么。
对于图的遍历,感觉只是树的二叉树的遍历的升级版。不同点是二叉树的每个结点最多只有2个孩子,而图的每个结点,与它相连的可能会很多,而且可能还会存在入度,出度等问题,这需要我们在写算法时更加细心;同时,我们还要考虑一个图是否有多个连通子图的问题。
在DFS中,mooc上点灯的例子很形象得展示了这个算法,是一个递归的过程,一直访问刚访问过的结点的第一个未被访问的邻接点,不断重复这个步骤直到刚访问过的结点没有未被访问的邻接点为止然后return回去。
在BFS中,也是使用了队列,将队头元素出栈,并将改结点的所有未被访问的邻接点入栈,重复这个步骤,直到队列为空。
在PTA的作业上,感觉作业里面的代码还是挺简单的,但是实践题要考虑很多问题。一开始代码只通过两个测试点,然后我找了下原因,发现我没有考虑另外两种情况:1.007在岛上一部1步就能走出;2.007甚至连踩到最近一条鳄鱼头上的机会都没有。在这个题中,我用了DFS,但是这个题和课本上的例子有点不同:不是简单的遍历,在遍历每个连同子图之前,我们都要把visited数字置为false,因为可以踩之前踩过的,而置为true的点表示,在这个点上没法跳出鳄鱼池。
最后改完可以通过测试点的代码如下:
#include <iostream> #include <math.h> using namespace std; bool visited[100]={false}; int answer = 0; typedef struct { int x;//横坐标 int y;//纵坐标 }Node; typedef struct { Node node[100]; int acrs[100][100];//邻接矩阵 int vexnum;//总点数 int step;//最大步数 }AMGraph; void input(AMGraph &g) { for(int i=0; i<g.vexnum; i++)//输入每一个鳄鱼的坐标 cin >> g.node[i].x>> g.node[i].y; //先初始化矩阵 for(int i=0; i<g.vexnum; i++) for(int j=0; j<g.vexnum; j++) g.acrs[i][j]=100; //写入距离 for(int i=0; i<g.vexnum; i++) for(int j=i+1; j<g.vexnum; j++) { double k, t; k=g.node[j].x-g.node[i].x; t=g.node[j].y-g.node[i].y; g.acrs[i][j]=sqrt(k*k+t*t); g.acrs[j][i]=sqrt(k*k+t*t); } } void DFS(AMGraph g, int i) { //使用DFS遍历,直到找到一个点和鳄鱼池边的距离小于step,即坐标大于等于 double k=fabs(g.node[i].x-50);//点的横坐标离鳄鱼池边缘的距离 double t=fabs(g.node[i].y-50); if(k<=g.step||t<=g.step) { answer = 1; return; } visited[i]=true;//visited[i]=true,说明这个点走过了,而且不能走出鳄鱼池 //遍历与i相连的结点 for(int j=0;j<g.vexnum;j++) { if(g.acrs[i][j]<=g.step&&visited[j]==false) DFS(g, j); } } void save(AMGraph g) { for(int i=0;i<g.vexnum;i++) { double k=fabs(g.node[i].x-15);//横坐标离岛边缘的距离 double t=fabs(g.node[i].y-15);//纵坐标离岛边缘的距离 //作为头结点,必须要能从岛走到那个点 if(k<=g.step||t<=g.step) { //与遍历所有结点不同,这里在每遍历一个连通分量之前,所有visited置为false for(int j=0;j<g.vexnum;j++) visited[j]=false; DFS(g, i); } } } int main() { AMGraph g; cin >> g.vexnum>> g.step; if(g.step>=50-15)//从岛的边一步就能走出鳄鱼池 { cout << "Yes"; return 0; } input(g); save(g); if(answer==1) cout << "Yes"; else cout << "No"; return 0; }
在第六章的学习,感觉有点难度但是也很有趣。在下一章希望能更高效得学习。