DS博客作业06--图

1.本周学习总结

1.1思维导图

1474872-20190602165320892-1451118703.png

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代码截图

1474872-20190608164119603-1894969677.png
1474872-20190608164544976-1168804508.png

1474872-20190608164406934-241799249.png

2.1.3本题PTA提交列表说明

1474872-20190530004328866-1844229331.png
Q1:部分测试点出现段错误
A1:数组容量不够大,增大数组大小即可
Q2:如何正确初始化
A2:初始化每条边权值为无穷,当i==j时,g[i][j]需记得置为0

2.2 题目2:7-3 六度空间 (30 分)

2.2.1设计思路(伪代码)

先上一个图解

1474872-20190608170435309-1055712424.png

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代码截图

1474872-20190608171728984-379982804.png
1474872-20190608171809245-479353091.png
1474872-20190608171829442-2063389692.png
1474872-20190608171839393-1488271631.png

2.2.3本题PTA提交列表说明

1474872-20190602165909046-38979240.png
1474872-20190602165816688-808189624.png

Q1:使用结构体数组的容量不够,多次调整大小,最后还是有一个测点过不了
1474872-20190602165745699-920572101.png
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代码截图

1474872-20190608181910169-1995538632.png
1474872-20190608181940697-725434342.png

2.3.3本题PTA提交列表说明

1474872-20190602202230672-47035544.png
Q1:使用menset()函数,有一定限制
A1:在主函数内使用一切正常,带入函数体内,返回主函数是会发生错误
Q2:怎么记录已经使用的颜色数目
A2:再建一个数组,以颜色为下标,遇到新颜色从0置为1,现在的颜色nowColor++

3.上机考试错题及处理办法

3.1错题:公路村村通

3.1.1截图错题代码

1474872-20190608205130335-181722997.png
1474872-20190608205156890-1503084662.png
1474872-20190608205213763-2120126009.png

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 错的原因及处理方法(此处换成本题代码)

1474872-20190608221326273-896751912.png

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 错的原因及处理方法(此处换成本题代码)

1474872-20190608223931143-741384477.png
1474872-20190608232430719-346195886.png
1474872-20190608233028416-787223761.png

1474872-20190608233037594-1902419276.png

转载于:https://www.cnblogs.com/linshuxin1761/p/10924694.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值