1.学习总结(2分)
1.1图的思维导图
图的存储结构--图的遍历---最小生成树--最短路径---拓扑排序、关键路径,这些知识点需要都梳理。
1.2 图结构学习体会
谈谈你对图结构中的几个经典算法学习体会。具体有:
1、深度遍历算法
深度遍历算法,是图论中的经典算法,慢慢去学还是比较好理解的。其利用深度优先搜索算法可以产生目标图的相应拓扑
排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。
2、广度遍历算法
广度遍历算法比较简单,较为容易理解和掌握。其基本思路为:
3、Prim和Kruscal算法
Prim算法和Kruskal算法都是从连通图中找出最小生成树的算法。从策略上来说,Prim算法是直接查找,多次寻找邻边的权重最小值,
而Kruskal是需要先对其权重排序之后再查找的。所以,Kruskal在算法效率上来讲是比Prim快的,因为Kruskal算法只需一次对权重的排
序就能找到最小生成树,而Prim算法则需要多次对邻边排序才能找到。
4、Dijkstra算法
Dijkstra算法是典型的最短路径算法,用于计算一个节点到其他节点的最短路径。
它的主要特点是以起始点为中心向外层层扩展(似于广度优先搜索的思想),直到扩展到终点为止。
5、拓扑排序算法
拓扑排序,是对有向无回路图进行排序,以其找到一个线性序列,这个线性序列在生活中可以表示某些事情完
成的相应顺序。如果说所求的图有回路的话,则不可能找到这个序列。
2.PTA实验作业(4分)
本周要求挑选出3道题目书写设计思路、调试过程。设计思路使用伪代码描述。题目选做要求:
- 不能选6-1,6-2,6-3
具体书写内容及格式如下:
2.1 题目1:7-1 图着色问题
2.2 设计思路(伪代码或流程图)
通过遍历找到所有的问题子集 ,但是在递归遍历的时候,都再加一个判断,将那些明显不满足条件的情况给直接排出,减少问题的规模,
其实这类问题,在递归遍历的时候都是类似与对一颗树的便利每个节点相当走到此时的状态,然后再判断此时的状态是否能继续走下去,
如果不能就将其回溯到上一个节点,避免浪费时间。
2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)
请贴主要函数代码,一些操作函数代码不需要贴图。
2.4 PTA提交列表说明。
PTA提交列表中的每个错误详细说明为什么及如何解决。
题目2,3同题目1
PTA提交列表中问题请务必详细说明问题原因及如何解决,否则一题没写扣2分
2.1 题目2:7-2 排座位
2.2 设计思路
因为朋友的朋友也是朋友,是传递关系,因此考虑并查集,将直接或间接是朋友关系的元素加入集合
而敌人的敌人不一定是敌人,所以只需要用一个二维数组即可标记。若两人是敌对关系,但同属于这个集合,
则符合题意中“OK but...”这种情况, 其余情况直接进行判断即可。
2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)
请贴主要函数代码,一些操作函数代码不需要贴图。
2.4 PTA提交列表说明。
PTA提交列表中的每个错误详细说明为什么及如何解决。
题目2,3同题目1
PTA提交列表中问题请务必详细说明问题原因及如何解决,否则一题没写扣2分
2.1 题目3:7-4 公路村村通
2.2 设计思路(伪代码或流程图)
建完图后
建立两个数组low[MAXV],clost[MAXV],来记录U到V-U之间选择权值在最小的边。
for(i=0 to i<g.n){
初始化low[i]的值和clost[i]=v的值。
end for
for(i=0 to i<g.n){
定义min=INF,min用来寻找最小边的权值。
for(j=1toj<g.n){
在(V-U)中寻找距离U最近的点
并定义k来记录最近顶点的编号。
}
让k节点进入U数组中
判断图是否联通 if(min=INF)说明道路没有立联通 输出-1;
节点k进入U数组后,
图与剩下节点的距离就会改变
因此
for(j=0 to j=G.n){
if(k节点到其他节点的距离更短) 修改low数组。
}
}
2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)
请贴主要函数代码,一些操作函数代码不需要贴图。
2.4 PTA提交列表说明。
PTA提交列表中的每个错误详细说明为什么及如何解决。
题目2,3同题目1
PTA提交列表中问题请务必详细说明问题原因及如何解决,否则一题没写扣2分
寻找最小权值的for循环之后,判断min的值是否改变,如果出现min值没有改变的情况
就说明图是不通的。
3.截图本周题目集的PTA最后排名(3分)
本次题目集总分:310分
3.1 PTA排名(截图带自己名字的排名)
3.2 我的总分:
220
本题评分规则:
(1)PTA总分310分:3分(全部题目都做)
(2)PTA总分在250分--310分:2.5分(大部分做完1)
(3)PTA总分在200--250分:2分(大部分做完2)
(4)PTA总分在150--200分:1.5分
(5)PTA总分在60分-150分:1分
(6)PTA总分在60分以下:0分
4. 阅读代码(必做,1分)
本次为必做
- 找一篇图结构应用代码
- 详细说明代码思想,学习地方。
要求实现利用图来完成一个校园导航程序。该程序应该可以显示多个地点的具体信息并显示出两地之间的所有路径和最短路径。
想法是先对顶点和要构建的网做一个结构定义,然后建立一个无向网,并用无向网表示校园景点的平面图。并用数组把所有
地点进行编号并把他们的信息同样放入数组保存。最后利用循环,标志确定,等一系列知识完成这个寻找路径的过程。
学习其构建网的方法,在实际中的应用。
#include<stdio.h>
#include<string.h>
#define MAXV 20
#define MAXSIZE 20
#define MAXLEN 500
#define INF 32767 /*用32767表示∞*/
int a=0;
顶点的结构定义
typedef struct {
int num;
char name[MAXSIZE];
char content[MAXLEN];
}VertexType;
网的结构定义
typedef struct {
int edges[MAXV][MAXV];
int vexnum,arcnum;
VertexType vexs[MAXV];
}MGraph;
int visited[MAXV];
int p[MAXV];
寻找路径函数:
void path(MGraph g,int i,int j,int k)
/*确定路径上第k+1个顶点的序号*/
{int s;
if(p[k]==j)/*找到一条路径*/
{
a++;/*路径的条数值加1*/
printf("第%d条:\n",a);
for(s=0;s<=k-1;s++)/*输出一条路径*/ printf("%s->",g.vexs[p[s]].name); printf("\n");
}
s=0;
while(s<g.vexnum)
{ if(s!=i) /*保证找到的是简单路径*/
{
if(g.edges[p[k]][s]!=INF&&visited[s]==0) /*当vk与vs之间有边存在且vs未被访问过*/
{ visited[s]=1; /*置访问标志位为1,即已访问的*/
p[k+1]=s; /*将顶点s加入到p数组中*/
path(g,i,j,k+1);
visited[s]=0; /*重置访问标志位为0,以便该顶点能被重新使用*/
}
}
s++;
}
}
输出路径函数:
void disppath(MGraph g,int i,int j)
{ int k; p[0]=i;
for(k=0;k<g.vexnum;k++)
visited[i]=0; /*初始化各顶点的访问标志位*/
a=0; /*初始化路径的条数*/
path(g,i,j,0); /*通过调用path函数,找到从vi到vj的所有路径并输出*/
}
确定最短路径函数:
void ppath(MGraph g,int path1[],int i,int v0)
{ int k;
k=path1[i];
if(k==v0) /*找到最短路径,则返回*/
return;
ppath(g,path1,k,v0); /*否则,递归调用之*/
printf("%s->",g.vexs[k].name) ; /*依次输出路径中的景点名称*/
}
计算最短路径函数:
void dispath(MGraph g,int dist[],int path1[],int s[],int n,int v0,int i)
{
if(s[i]==1&&i!=v0) /*当v0不等于i,且i∈s*/
{ printf("从%s到%s的最短游览路径是:\n",g.vexs[v0].name,g.vexs[i].name);
printf("%s->",g.vexs[v0].name);
ppath(g,path1,i,v0) ; /*调用ppath函数,输出路径中的顶点*/
printf("%s ",g.vexs[i].name);
printf("路径长度:%d米\n",dist[i]);
}
}
输出最短路径函数:
Void Dijkstra(MGraph g,int v0,int p)
{
int dist[MAXV],path1[MAXV]; int s[MAXV];
int mindis,i,j,u,n=g.vexnum;
for(i=0;i<n;i++)
{ dist[i]=g.edges[v0][i]; /*距离初始化*/ s[i]=0;/*s[]置空*/
if(g.edges[v0][i]<inf) *路径初始化*=""
path1[i]="v0;
else
path1[i]=-1; }
s[v0]=1;path1[v0]=0; /*源点编号v0放入s中*/
for(i=0;i<n;i++)
{ mindis="INF;
" u="-1;
for(j=0;j<n;j++) * 选取不在s中具有最小距离的顶点u*=""
if(s[j]="=0&&dist[j]<mindis)
{ u=j;
mindis=dist[j]; }
s[u]=1; /*顶点u加入s中*/
for(j=0;j<n;j++)
if(s[j]="=0)<br" *修改不在s中的顶点的距离*="">
if(g.edges[u][j]<inf&&dist[u]+g.edges[u][j]<dist[j]) *修正dist[i],path1[i]*=""
{dist[j]=dist[u]+g.edges[u][j];
path1[j]=u; } }
dispath(g,dist,path1,s,n,v0,p);/*输出最短路径*/
}
查询景点信息函数:
void Searchname(MGraph g)
{ printf("景点:\n1:体育馆\n2:中邦楼\n3:文汇楼\n4:西门\n5:食堂\n6:格物楼\n7:力行楼\n8:楠苑\n9:梓苑\n10:实验楼\n11:图书馆\n");
int i; char s;
printf("选择:"); scanf("%d",&i);
for(int j=0;j<g.vexnum;j++) <br="" *g.vexnum表示网中的顶点个数*="">
if(i==g.vexs[j].num) / *在网中找到其编号与输入的顶点编号相同的顶点*/
{printf("%s简介:\n",g.vexs[j].name); /*输出顶点的名称*/
printf("%s",g.vexs[j].content); /*输出顶点的简介信息*/
printf("\n");
} }
查询所有路径函数:
void Searchpath1(MGraph g)
{ printf("景点:\n1:体育馆\n2:中邦楼\n3:文汇楼\n4:西门\n5:食堂\n6:格物楼\n7:力行楼\n8:楠苑\n9:梓苑\n10:实验楼\n11:图书馆\n");
int i,j; char s;
printf("选择出发景点:"); scanf("%d",&i);
printf("选择目地景点:"); scanf("%d",&j);
for(int k=0;k<g.vexnum;k++) /*g.vexnum表示网中的顶点个数*/
if(i==g.vexs[k].num) i=k; /*在网中找到其编号与输入的出发景点的编号相同的顶点*/
for(int l=0;l<g.vexnum;l++)
if(j==g.vexs[l].num)
j=l; /*在网中找到其编号与输入的目地景点的编号相同的顶点*/
printf("从%s到%s的所有游览路径有:\n",g.vexs[i].name,g.vexs[j].name); /*输出出发景点和目地景点的名称*/
disppath(g,i,j); /*调用disppath函数,用来输出两个景点间的所有路径*/
}
查询最短路径函数:
void Searchpath2(MGraph g)
{printf("景点:\n1:体育馆\n2:中邦楼\n3:文汇楼\n4:西门\n5:食堂\n6:格物楼\n7:力行楼\n8:楠苑\n9:梓苑\n10:实验楼\n11:图书馆\n");
int i=0,j=0; char s=0;
printf("选择出发景点:");
scanf("%d",&i);
printf("选择目地景点:" );
scanf("%d",&j);
for(int k=0;k<g.vexnum;k++) *g.vexnum表示网中的顶点个数*="">
if(i==g.vexs[k].num)
i=k; /*在网中找到其编号与输入的出发景点的编号相同的顶点*/
for(int l=0;l<g.vexnum;l++)
if(j==g.vexs[l].num) j=l; /*在网中找到其编号与输入的目地景点的编号相同的顶点*/
Dijkstra(g,i,j); /*调用Dijkstra函数,用来输出两个景点间的最短路径*/ }
l
5.评分说明
- 每题都是必做题,都需要按照要求去独立写及完成,有任何一题没做,总分最高5分。
- 做作业是一种态度,我们更看重你对作业及课程的学习态度。你可以有不会或不懂,但请你详细说明不会不懂地方在哪,PTA列表错误怎么解决不了,不要给我们一片空白。
- 希望你认真对待,我们也会认真去批改。