DS博客作业06--图
1.本周学习总结
1.1思维导图
1.2谈谈你对图结构的认识及学习体会
- 对于图结构的认识,图结构的存储分为临邻接矩阵和邻接表,邻接表的遍历时间复杂度会比较小为O(n+e),邻接矩阵为O(N^2),但是我还是比较喜欢使用邻接矩阵,感觉在运用上会比较熟练容易一点,在PTA的7-1图着色问题,六度空间问题都使用矩阵进行存储;图的遍历分为深度遍历(DFS)和广度遍历(BFS),深度遍历因为使用递归在相应的代码量上会比较少一点,但广度遍历个人感觉会比较好运用一点。还有最小生成树和最短路径问题,感觉应该多看代码,每看一次印象会比较深刻,还有Prim算法中lowcost[]和closest[]数组,刚开始总会写成二维数组,然后发现编译错误,哈哈
- 不知怎么的感觉最近学习总是有点赶,可能是临近期末了,最近感觉学得比较理论化的东西,学的几个算法也不怎么熟悉,最小生成树和最短路径问题每两种算法代码估计都只会一种,另一种只会理论上画图,马马虎虎地过去,遗忘得也快,经常记混。
2.1.题目1:7-4 公路村村通 (30 分)
2.1.1设计思路(伪代码)
变量顶点v,边数e,cost权值
int main()
{
for i=1 to n
for j=1 to n
使边的初始长度都为无穷
for i=0 to e//输入边信息
g[v][re]=cost
g[i][i]=0
//图构建完毕,开始用prim算法进行查找,从顶点1开始
for i=1 to n
lowcost[i]=g[1][i];//对顶点1所相邻的边进行初始化
closest[i]=1;
找n-1条边
for i=1 to n-1
先令最小值等于无穷
for j=1 to n
找lowcost[]数组最小的边,赋值给min
用k记录该边所对应的顶点
检查min是否还是等于无穷,是的话输出-1,return 0
将lowcost[k]置为0,表明不再选取
num+=min//记录
for j=1 to n
对顶点1所相邻的边进行遍历,保存在lowcost[]中
有更小的替换掉,所相邻的边对应的顶点为k
如此循环n-1次
}
2.1.2代码截图
2.1.3本题PTA提交列表说明
Q1:部分测试点出现段错误
A1:数组容量不够大,增大数组大小即可
Q2:如何正确初始化
A2:初始化每条边权值为无穷,当i==j时,g[i][j]需记得置为0
2.2 题目2:7-3 六度空间 (30 分)
2.2.1设计思路(伪代码)
先上一个图解
int main()
{
输入顶点数和边数;
将数组g[][]每个元素置为0 memset(g,0,sizeof(g));
将数组visited[]每个元素置为0;
for i=0 to e//输入边信息
cin>>v>>re;
g[v][re]=g[re][v]=1;
for i=0 to n
将数组visited[]每个元素置为0;
BFS(i)//将每个顶点都带入1次
}
void BFS(int v) //广度遍历
{
queue<int>q;//存储上一圈被圈住的元素
queue<int>vx;//存储被pop的上一圈被圈住的元素
先把第一个顶点放入q中
while(c--)//循环6次
while(!q.empty())
将q中的元素,存到vx,然后pop
while(!vx.empty())
将与队列vx中元素相邻未被数组visited置为1的顶点放入q中
用num计算被圈的个数 num++;
vx.pop();
输出百分比
}
2.2.2代码截图
2.2.3本题PTA提交列表说明
Q1:使用结构体数组的容量不够,多次调整大小,最后还是有一个测点过不了
A1:使用全局变量的数组
Q2:怎么队列里的顶点都循环一遍,而不是一个循环一遍
A2:再设一个队列存出队的顶点
2.3 题目3:7-1 图着色问题 (25 分)
2.3.1设计思路(伪代码)
int judge()
{
对g[][]进行遍历
if g[i][j]==1&&color[i]==color[j]//相邻的颜色一样
return 0;
return 1;
}
int main()
{
将数组g[][]每个元素置为0 memset(g,0,sizeof(g));
for i=0 to e//输入边信息
cin>>v>>re>>vcolor;//vcolor为规定的颜色数目
g[v][re]=g[re][v]=1;
输入要填涂的组数
while(count--)
{
memset(colorNum,0,sizeof(colorNum));//将记录颜色的数组colorNum[]置为0
for(int i=1;i<=n;i++)
输入颜色
if(colorNum[color[i]]==0)//发现新颜色
colorNum[color[i]]置为1
nowColor++;//记录当前颜色数
if 当前颜色数不等于规定颜色数
falg=0;
通过判断judge和flag输出Yes和No
}
2.3.2代码截图
2.3.3本题PTA提交列表说明
Q1:使用menset()函数,有一定限制
A1:在主函数内使用一切正常,带入函数体内,返回主函数是会发生错误
Q2:怎么记录已经使用的颜色数目
A2:再建一个数组,以颜色为下标,遇到新颜色从0置为1,现在的颜色nowColor++
3.上机考试错题及处理办法
3.1错题:公路村村通
3.1.1截图错题代码
3.1.2 错的原因及处理方法
错误原因:
1.根据Prim算法应该寻找n-1边,而以上代码是循环找n条边
2.循环的括号扩错地方了,变成只能找一条边
处理方法:
在第39行的<=改成<;第47行括号移到58行后面
3.2错题:jmu-ds-最短路径 (上机考时没写)
3.1.1截图错题代码(此处换成本题伪代码)
void Dijkstra(MatGraph g,int v)
{
for(i=0;i<g.n;i++)
dist[i]=g.edges[v][i]//初始化
s[]置空
if 有边
path[i]=v;//记录
else
path[i]=-1;//没边
将v放进s[]中
for(i=0;i<g.n-1;i++)
先令最小值等于无穷
for(j=0;j<g.n;j++)
找dist[]数组最小的边,赋值给min
用k记录该边所对应的顶点
s[k]=1//将k放进s[]中
for(j=0;j<g.n;j++)//修改不在U中的顶点的距离
if(还没被放入s中)
if 有边且路径和最短
dist[j]=dist[k]+g.edges[k][j];
path[j]=k;
Dispath(dist,path,s,n,v)//输出
}
3.1.2 错的原因及处理方法(此处换成本题代码)
3.3错题:天梯地图 (上机考时没写)
3.1.1截图错题代码(此处换成本题伪代码)
用dijkstra算法计算路程
用dijkstra算法计算时间
上题有写到dijkstra算法此处省略
void path(int pre[600],int p)
{
if 起点等于终点
return;
else
Path(pre,pre[p]);
printf(" %d =>",pre[p]);
}
int cmp(int pd,int pt)
{
if 最少花费和最短时间路径不相等
return 0;
else if 最少花费和最短时间路径或起点与终点相等
return 1;
return cmp(preDist[pd],preTime[pt]);
}
int main()
{
mapDist,mapTime数组初始化为无穷
输入标记地点的个数和连接地点的道路条数
for (int i=0;i<连接地点的道路条数;i++)
输入s,e,flag,cost,t//端点的编号,单双行线,花费,时间
mapDist[s][e]=cost;
mapTime[s][e]=t;
if (!flag)
mapDist[e][s]=cost;
mapTime[e][s]=t
输入出发地点和终点s,e
dijkstraDist();
dijkstraTime ();
if 两条路径一样
Path(preDist,e);
else
Path(preTime,e);
Path(preDist,e);
return 0;
}
3.1.2 错的原因及处理方法(此处换成本题代码)