DS博客作业06--图
DS博客作业06--图
1.本周学习总结(0--2分)
1.思维导图
2.谈谈你对图结构的认识及学习体会。
1.比起前一章的树,图的结构体、基础函数等都会简单一些,结构体很简单,基本函数也没有像树那样经常用到递归,但是那些Prim等算法还是需要花点时间去理解的。
2.图的存储结构分为邻接矩阵和邻接表,邻接矩阵适用于稠密图,邻接表适用于疏密图。用邻接矩阵进行BFS、DFS,用邻接表进行BFS、DFS遍历的操作都需要我们非常熟悉。
3.当在一个不带权图中搜索从一个顶点到另一个顶点的一条路径时,DFS求出的路径不一定时最短路径,而BFS求出的路径一定是最短路径。
4.Prim算法和克鲁斯卡尔算法都是求最小生成树的算法,采用邻接矩阵最合适。从理论上来讲(不看代码),克鲁斯卡尔算法更容易理解,只要将线段从小到大排序后再连接就好了,但是Prim算法在代码上更容易实现。
5.Dijkstra算法和Floyd算法,前者输出单源路径,后者输出多源路径。.Dijkstra算法其实和Prim算法有很多相似,但需要修正的数据会比Prim算法多。
2.PTA实验作业(6分)
2.1.题目1:题目名称:图着色问题
图着色问题是一个著名的NP完全问题。给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色?
但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。
2.1.1设计思路(伪代码)
文字描述:
用邻接矩阵存储图结构,将颜色的编号存入相应的color数组,然后遍历邻接矩阵,不断的比较两个有连线的顶点的颜色。
伪代码
定义n为顶点个数,e为边数,colorNum为题目要求的颜色数,T为颜色方案的数目,colorCount为用于计算给出的颜色的种类数,color数组用于存放各个顶点对应的颜色;
定义一个MGraph型变量g;
定义flag1变量来控制颜色的种类的统计;
定义flag2变量来判断两个连通的顶点的颜色是否相同;
输入n,e,colorNum;
创建以邻接矩阵为存储结构的图结构g;
输入方案数T;
while T--!=0 do
初始化,flag2=1,颜色种类colorCount=0;
初始化color数组;
/*计算颜色的种类,并存在数组color中*/
for i=1 to i<=g.n do
初始化flag1=1;
输入color[i];
/*遍历之前的color数组,看颜色有没有重复*/
for j=1 to j<i do
if 有相同的颜色 then
flag1=0;
break;
end if
end for
if flag1=1 then
colorCount++;
end if
end for
if 给出的颜色数组!=题目要求的颜色数目 then
输出No;
continue;
end if
/*遍历邻接矩阵*/
for i=0 to i=n do
for j=0 to j=n do
if 两个顶点之间连通且颜色相同 then
flag2=0;
break;
end if
end for
if flag2=0 then
break;
end if
end for
if flag2=0 then
输出No;
end if
if flag=1 then
输出Yes;
end if
end while
2.1.2代码截图
2.1.3本题PTA提交列表说明。
- Q1:那么多的编译错误。
- A1:很显然,没有将C改成C++。
- Q2:有小于k种颜色时错误。
- A2:题目理解不清,以为只要用的颜色数目<=题目要求的数目就可以了,结果是必须要用的颜色数目=题目要求的数目才能过。
- Q3:最大图时错误。
- A3:因为在邻接矩阵的创建,是直接复制粘贴以前写过的题目,MAXV的限制不同,改过来就好了。
2.2 题目2:7-3 六度空间
“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”“六度空间”理论虽然得到广泛的认同,并且正在得到越来越多的应用。但是数十年来,试图验证这个理论始终是许多社会学家努力追求的目标。然而由于历史的原因,这样的研究具有太大的局限性和困难。随着当代人的联络主要依赖于电话、短信、微信以及因特网上即时通信等工具,能够体现社交网络关系的一手数据已经逐渐使得“六度空间”理论的验证成为可能。假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。
2.2.1设计思路(伪代码)
设计思路
将图结构用矩阵存着,然后通过广度遍历来计算每个相隔不超过5的结点数目。
伪代码
定义结点数n和边数e;
定义顶点访问标记数组visited[MAXV];
定义一个充当邻接矩阵的二维数组edgex[MAXV][MAXV];
int main()
输入n和e
for i=1 to e do
输入边的关系;
将edgex[][]对应的点的值改为1;
end for
for i=1 to n do
初始化visited数组 ;
调用BFS函数,返回距离不超过5的结点数;
计算并输出百分比;
end for
int BFS(int v)
定义一个队列qu;
将v入队;
visited[v]=1;
while 队不空且距离小于6 do
取队首做临时调用点temp;
循环遍历与该结点相连接的点
if 结点未遍历 then
结点数++;
入队;
visited[i]=1;
记录位置tail=i;
end if
if temp==last then
记录当前层数的最后一个元素的位置 ;
结点层数加一;
end if
end while
return count;
2.2.2代码截图
2.2.3本题PTA提交列表说明。
- Q1:刚开始思路很乱,知道用广度遍历BFS去求结点,但是还是卡壳了。
- A1:这题不仅要用广度遍历BFS,还要和递归相结合,分层运算。
- Q2:最开始想用邻接矩阵的结构来做,但是一直段错误。
- A2:问题是出在MAXV=10001时,整个数组超限,跑不动。所以后来就直接用数组做。
2.3 题目3:7-4 公路村村通
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。
输出格式:
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。
2.3.1设计思路(伪代码)
设计思路
用邻接矩阵存储图结构,再用Prim算法,找最小生成树。
伪代码
定义Minimum为无穷大量
定义二维数组edgex[][]存放边的信息
定义visiedt数组存放被访问过的结点
定义lowcost存储每个顶点与之相连边的权值
int main():
输入n,e;
为map与visit置初值;
while e--!=0 do
输入u,v,权重w;
将边的信息存入二维矩阵edgex[][]中;
end while
调用Prim函数;
return 0;
int prim():
定义总成本sum =0;
定义flag=0;用于判断道路是否畅通;
visited[1]=1;
权值初始化;
for i=2 to n do
Min = Minimum;
/*寻找每个顶点与之相连的边的最小权值*/
for j=1 to n do
if !visit[j]&&lowcost[j]<Min then
Min = lowcost[j];
k=j;
end if
end for
if 某个顶点与之相连的边找不到最小权值即Min==Minimum then
flag = 1;
break;
end if
sum+=Min;
标记该结点visited[k]=1;
/*修正权值*/
for j=1 to n do
if !visit[j]&&lowcost[j]>Map[j][k] then
lowcost[j]=Map[j][k];
end if
if flag=0 then
输出sum;
end if
if flag=1 then
输出-1;
end if
2.3.2代码截图
2.3.3本题PTA提交列表说明。
- Q1:那个多种错误。。。
- A1:把7-3的六度空间的答案提交到这里,能过才有鬼。
- Q2:不管输入什么,输出的答案都是0。
- A2:通过调试发现一个很傻的问题👇
没错,就是这个基础性的错误(丢人)
3、上机考试错题及处理办法
3.1.截图错题代码
题目:6-1 最短路径
给定一个有向图,规定源点为0,求源点0到其他顶点最短路径。
上机写出来bug还没调完,时间就截止了(菜狗,自闭)。所以回来重写,直接上代码。
3.2 错的原因及处理方法
- Q1:眼睛瞎了,题目提示顶点从0开始,我愣是没把它当回事,写for循环i=1写的特别欢快。
- A1:还能咋整,改呗。(心痛)
- Q2:忘记将min再次初始化
- A2:如下图。