DS博客作业06--图

1.本周学习总结

1.1思维导图

1474626-20190603185408214-14324789.png

1.2谈谈你对图结构的认识及学习体会

到了图结构,数据结构更加体现出来它在生活中的实际应用,包括最小路径寻找以及最小生成树,因此他也显得很重要,不仅仅是在将来的工作或者工作面试,亦或者是acm的比赛中都需要大范围的使用。其实在学习图结构之前,我完全不知道该怎么存储一个图结构,树还能想象,后来发现图的存储其实很简单粗暴,但是也十分实用,对于不同的算法也都有不同的存储结构,可以说是很神奇了。然而这一章节的学习也需要花时间去理解,复习。

2.PTA实验作业

2.1.题目1:7-4 公路村村通

题目描述

现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式
输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。
输出格式
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。

2.1.1设计思路

自从上次梅梅在我面前秀过一手优先队列我就对这个容器爱不释手,配合优先队列,我决定采用克鲁斯卡尔算法再加以并查集的辅佐来完成这一个题目
在这之前要解决几个问题:
1.首先是优先队列中的比较问题,对于一个int型或者double型的变量进行操作当然容易,可对于一个结构体,如何传入一个已有的函数让他进行比较呢。这里就需要在结构体中对比较符号进行重载,使得我们能直接对结构体进行比较。
2.其次是优先队列中的排序问题,优先队列时默认从从大到小排列的,但是我们这里最小生成树需要的是从小到大,所以我们就需要在定义优先队列的时候采用小顶堆进行排序。

priority_queue<Road, vector<Road>, greater<Road>> all //首先定义一个all优先队列
int count //计算已经存储的道路
int cost //记录消费
for i=1 to road:
    将已有的道路信息传入队列;
for i=0 to town:
    初始化并查集
while all.size():
    temp=all.front()
    all出队
    if(temp.town1和temp.town2不连通):
        Union(town1,town2)合并两个村;
        cost更新;
        count++;
输出cost

2.1.2代码截图

1474626-20190526165211569-1908908830.png

2.1.3本题PTA提交列表说明

1474626-20190526170334714-1209396690.png

WA:这两个错误的原因其实都一样,就是当不连通的时候没有办法判断,之所以第一个错误多了两分是因为我加了个if语句判断M<N-1的情况,后来我发现只要统计一下在操作过程中连接上的道路数目是不是等于城镇数减一就好了。

2.2.题目2:7-7 旅游规划

题目描述

有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。
输出格式
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。

2.2.1设计思路

思路一:这题我是用弗洛伊德算法去做的,心想平常的课后作业应该不会很难,所以时间复杂度高一点应该没问题,原本的使用一个int矩阵去实现的,但是这里多了一个价格的选项,所以我们设计一个结构体来存储这些数据

typedef struct road {
    int dist;//距离
    int cost;//消费
}Road;

伪代码如下:

Road matrix[MAX]
cin >> n >> m >> s >> d;
初始化矩阵所有元素为INF
while m--:
    读取路径信息到矩阵
弗洛伊德算法
for k=0 to n-1:
    for i=0 to n-1:
        for j=0 to n-1:
            if matrix[i][j].dist > matrix[i][k]+matrix[k][j].dist:    //原路径比新路径长
                更新matrix[i][j]的cost和dist

            else if 原路径等于新路径:
                if 原路径消费 > 新路径:
                    更新matrix[i][j]的cost和dist

            else 保持不变

cout << matrix[s][d].dist << ' ' << matrix[s][d].cost;

思路二:Dijskstra算法
对于这个算法来讲,只要在课本上算法的基础上增加一个cost数组数组用来记录消费就可以了,然后最后进行修正的时候如果找到路程相等的就直接比较他们的消费就醒行了

2.2.2代码截图

思路一:
1474626-20190526165224890-522907055.png

思路二:
1474626-20190602172047283-1656676119.png
1474626-20190602172103713-435140018.png

2.2.3本题PTA提交列表说明

1474626-20190526170657168-633718784.png

WA:这里错误是因为我忽略了他是一个无向图,一开始当成有向图做了,只要在初始化路径信息时添加上面两条语句就好啦。

2.3.题目3:7-3 六度空间

题目描述

“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图1所示。
1474626-20190526163747638-1981268142.png
“六度空间”理论虽然得到广泛的认同,并且正在得到越来越多的应用。但是数十年来,试图验证这个理论始终是许多社会学家努力追求的目标。然而由于历史的原因,这样的研究具有太大的局限性和困难。随着当代人的联络主要依赖于电话、短信、微信以及因特网上即时通信等工具,能够体现社交网络关系的一手数据已经逐渐使得“六度空间”理论的验证成为可能。假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。
输入格式
输入第1行给出两个正整数,分别表示社交网络图的结点数N(1<N≤10​4​​,表示人数)、边数M(≤33×N,表示社交关系数)。随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个结点的编号(节点从1到N编号)。
输出格式
对每个结点输出与该结点距离不超过6的结点数占结点总数的百分比,精确到小数点后2位。每个结节点输出一行,格式为“结点编号:(空格)百分比%”。

2.3.1设计思路

这道题目我想采用vector来做,vector相当于一个可增加的数组,这样一来也就相当于在用邻接表了
至于认识的人,我用set容器来存储,因为set不会存储重复数据,但其实直接用count来统计人数也行,我一开始是想六个层次无脑塞进set容器,这样直接取size就可以了,但是后来发现这样会导致大数据内存爆掉
遍历方式采用广度遍历,符合题意

main函数:

cin >> n >> e;
set<int> check;
vector<int> point[MAX];
while e--:
    循环读取人脉信息到point里面
for i=1 to n:
    初始化vis为0
    BFS(i, 0)
    清空check

BFS函数:int i,int c;

queue<int> q;
q.push(i)
check.insert(i)
for i=1 to 6:
    vector<int> store;
    转移q中的数据到store
    for i=0 to store.size()-1:
        int temp=store[i]
        将temp的下一个节点全部入队q

2.3.2代码截图

1474626-20190526165242516-1723404908.png

2.3.3本题PTA提交列表说明

1474626-20190526170929663-1783790735.png

WA:这道题目是缠了我比较久的,我用vector去做,但是不管怎么样最后一个点总是内存超限,我真的超级纳闷,照理说这个vector应该类似于邻接表了,怎么还会内存超限,我一开始代码是这样的
1474626-20190526171233428-1720614022.png
后来思索了好久
1474626-20190526171321982-918890334.png
我将每一层的子元素入队时没有判断是否曾经访问过,直接全部入队,难道时因为这个爆了???遂增加vis数组判断是否访问过
然后就过了
1474626-20190526171902578-2085505896.png

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

3.1.截图错题代码

这几题都没做出来,就不贴错题代码了。。。我后面把这些题目又重做了一遍
题目1:最短路径
修改后的代码
1474626-20190603002521112-454991685.png

题目2:公路村村通
这道题目并不需要记录上一个点的位置,就不用像书本一样多一个数组了
修改后的代码
1474626-20190603181410775-1723059226.png
1474626-20190603181432888-1495836347.png

3.2 错的原因及处理方法

这词上机考试,原想剑走偏锋,未曾想被当场制裁,究其原因,就是没有好好去练习图结构,对图结构的一些算法也了解不是很清楚,还是应该好好反思一下自己。

转载于:https://www.cnblogs.com/Rasang/p/10926513.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值