数据结构:图

1.学习总结

(1)掌握图的相关概念,包括图、有向图、无向图、完全图、子图、连通图、度、入度、出度、简单回路和环等定义。

(2)重点掌握图的各种存储结构,包括邻接矩阵和邻接表等。

(3)重点掌握图的基本运算,包括创建图、输出图、深度优先遍历、广度优先遍历等。

(4)掌握图的其他运算,包括最小生成树、最短路径、拓扑排序和关键路径等的算法。

(5)灵活运用图这种数据结构解决一些综合应用问题。

1.1图的思维导图

1.2图结构学习体会

  • 深度遍历算法:一条路走到底,没路时再返回上一个找其他路,循环操作到遍历完所有顶点为止。
  • 广度遍历算法:先输出与首个顶点有路的所有顶点,再按先进先出法则输出与该顶点有路的顶点。
  • Prim和Kruscal算法:均为求最小生成树的算法,前者时间复杂度为O(n^2),后者为O(elog2(e))。
  • Dijkstra算法:以邻接矩阵作为存储结构,其算法时间复杂度为O(n^2)。
  • 拓扑排序算法:有向图,用邻接表定义,从入度为0的点出发走到没有前驱的顶点。

2.PTA实验作业

2.1.1题目1:图着色问题

2.1.2设计思路

直接用图的遍历,遍历的时候判断是否颜色相等即可。任选一顶点着色1,在图中尽可能多的用颜色1着色,当不能用颜色1着色时,转用其他颜色,直到所有顶点都被着色为止。(PS:伪代码思路为最初思路,实际代码已经修改成更精简的方法)

伪代码:

while each vertex in G 初始化颜色为0

vertex[0]=1//选初始点颜色置为1

置颜色种类color=0;

循环置所有顶点着色

color++;//取下一颜色

while each vertex in G

if vertex[i]已着色,转下一顶点

else

若该点用color着色与其他邻接点颜色不冲突

vertex[i]=color;

否则不着色

2.1.3代码截图

2.1.4PTA提交列表说明

开始的多次编译错误是因为代码使用的是C++,而PTA的初始编译器是C(gcc),经发现并改正后得以解决。答案错误是因为没有按照格式输出,部分正确是因为对题目的多种情况考虑不全,几经修改,最后答案正确。

2.2.1题目2:排座位

2.2.2设计思路

假设俩人A和B,需考虑如下情况:

(1) 如果A、B是直接的朋友,输出 No problem 
(2)否则如果A、B不敌对,输出OK 
(3)否则如果A、B敌对但他们有共同的朋友,输出OK but... 
(4)否则A、B敌对并且没有共同的朋友,输出No way

2.2.3代码截图

2.2.4PTA提交列表说明

开始的编译问题依然是编译器的选择问题,随后的答案错误是因为输出格式没有严格按照要求,紧接着的多次部分正确是因为题目的多种情况没整理完全,经一步步的完善后答案正确。

2.3.1题目3:六度空间

2.3.2设计思路

该题主要是解决超时的问题卡的比较久。 
比如像visited[],不是简单的0.1定义,不然每对一个数字进行遍历都还要重置visited[]。

2.3.3代码截图

2.3.4PTA提交列表说明

编译错误依旧是编译器的选择问题,多次答案错误是因为没有深入理解题意,以致于错漏百出,几番周折后答案正确。

3.本周PTA题目集最后排名截图

本次题目集总分:135分(时间:2018/6/17 13:12)

3.1PTA排名

47

3.2我的总分

135

4.阅读代码

天梯地图代码阅读:

最短路,麻烦的是多条最短路中推荐最优的路线,并输出路径。路径的还原可以不断记录前驱节点,注意的是每个节点的前驱节点可能不止一个,全需要记录,最后搜索最优路径。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <string>
  6. #include <algorithm>
  7. #include <cmath>
  8. #include <map>
  9. #include <queue>
  10. #include <stack>
  11. #include <set>
  12. using namespace std;
  13. const int INF = 0x3f3f3f3f;
  14. const int maxn = 1e4+10;
  15. /*----------------------------------------------------------------head------------------------------------------------------------------*/
  16. int n,m,ss,dd;
  17. int T[510][510],D[510][510],dist[510],disd[510],vist[510],visd[510],pret[510]/*记录最小时间的前驱*/,pred[510]/*记录最短距离的前驱*/,SUM[510]/*记录节点个数*/;
  18. int u,v,is,d,t;
  19. void print(int cnt,int c[]){//打印路径
  20. for(int i = cnt-1; i >= 0; i--){
  21. if(i != cnt-1)
  22. printf(" =>");
  23. printf(" %d",c[i]);
  24. }
  25. puts("");
  26. }
  27. /*------------------------------------------------------------dijkstra-----------------------------------------------------------------*/
  28. //求解最小时间的最短路
  29. void dijkstraT(){
  30. for(int i = 0; i < n; i++){//初始化
  31. dist[i] = T[ss][i];
  32. disd[i] = D[ss][i];
  33. vist[i] = visd[i] = 0;
  34. pret[i] = pred[i] = ss;
  35. }
  36. dist[ss] = disd[ss] = 0;//初始化
  37. vist[ss] = visd[ss] = 1;//初始化
  38. pret[ss] = -1;//初始化
  39. int Min,pos;
  40. for(int i = 1; i < n; i++){
  41. Min = INF;
  42. for(int j = 0; j < n; j++){
  43. if(!vist[j] && dist[j]<Min){
  44. Min = dist[j];
  45. pos = j;
  46. }
  47. }
  48. vist[pos] = 1;
  49. for(int j = 0; j < n; j++){
  50. if(!vist[j] && dist[j]>dist[pos]+T[pos][j]){
  51. dist[j] = dist[pos]+T[pos][j];
  52. disd[j] = disd[pos]+D[pos][j];
  53. pret[j] = pos;
  54. }
  55. else if(!vist[j] && dist[j] == dist[pos]+T[pos][j]){
  56. if(disd[j] > disd[pos]+D[pos][j]){//时间相同选距离最短
  57. disd[j] = disd[pos]+D[pos][j];
  58. pret[j] = pos;
  59. }
  60. }
  61. }
  62. }
  63. }
  64. //求解最短距离的最短路
  65. void dijkstraD(){
  66. for(int i = 0; i < n; i++){//初始化
  67. disd[i] = D[ss][i];
  68. visd[i] = 0;
  69. pred[i] = ss;
  70. SUM[i] = 1;
  71. }
  72. disd[ss] = 0;//初始化
  73. visd[ss] = 1;//初始化
  74. pred[ss] = -1;//初始化
  75. int Min,pos;
  76. for(int i = 1; i < n; i++){
  77. Min = INF;
  78. for(int j = 0; j < n; j++){
  79. if(!visd[j] && disd[j]<Min){
  80. Min = disd[j];
  81. pos = j;
  82. }
  83. }
  84. visd[pos] = 1;
  85. for(int j = 0; j < n; j++){
  86. if(!visd[j] && disd[j]>disd[pos]+D[pos][j]){
  87. disd[j] = disd[pos]+D[pos][j];
  88. pred[j] = pos;
  89. SUM[j] = SUM[pos]+1;
  90. }
  91. else if(!visd[j] && disd[j]==disd[pos]+D[pos][j]){//距离相同选节点数最小
  92. if(SUM[j] > SUM[pos]+1){
  93. SUM[j] = SUM[pos]+1;
  94. pred[j] = pos;
  95. }
  96. }
  97. }
  98. }
  99. }
  100. /*------------------------------------------------------------main--------------------------------------------------------------------*/
  101. int main(){
  102. scanf("%d %d",&n,&m);
  103. memset(T,INF,sizeof(T));
  104. memset(D,INF,sizeof(D));
  105. while(m--){
  106. scanf("%d %d %d %d %d",&u,&v,&is,&d,&t);
  107. if(is){
  108. if(T[u][v]>t)//去重
  109. T[u][v] = t;
  110. if(D[u][v]>d)//去重
  111. D[u][v] = d;
  112. }
  113. else{
  114. if(T[u][v]>t)//去重
  115. T[u][v] = T[v][u] = t;
  116. if(D[u][v]>d)//去重
  117. D[u][v] = D[v][u] = d;
  118. }
  119. }
  120. scanf("%d %d",&ss,&dd);
  121. dijkstraT();
  122. dijkstraD();
  123. int pt = dd;
  124. int pd = dd;
  125. int flag = 1;//flag==1表示两条路径相同,不然不同。
  126. int a[510],b[510],cnta,cntb;
  127. cnta = cntb = 0;
  128. while(pt != -1){
  129. a[cnta++] = pt;
  130. pt = pret[pt];
  131. }
  132. while(pd != -1){
  133. b[cntb++] = pd;
  134. pd = pred[pd];
  135. }
  136. if(cnta != cntb)//节点数不同路径肯定不同
  137. flag = 0;
  138. else{
  139. for(int i = 0; i < cnta; i++){
  140. if(a[i] != b[i]){
  141. flag = 0;
  142. break;
  143. }
  144. }
  145. }
  146. if(flag){
  147. printf("Time = %d; Distance = %d:",dist[dd],disd[dd]);
  148. print(cnta,a);
  149. }
  150. else{
  151. printf("Time = %d:",dist[dd]);
  152. print(cnta,a);
  153. printf("Distance = %d:",disd[dd]);
  154. print(cntb,b);
  155. }
  156. return 0;
  157. }

原文地址:https://www.cnblogs.com/999ganmaoling/p/9191389.html

时间: 2024-11-09 08:05:44

数据结构:图的相关文章

?数据结构-图之强连通

数据结构-图之强连通 在一个无向图G中,若从顶点v_i到顶点v_j有路径相连(当然从v_j到v_i也一定有路径),则称v_i和v_j是连通的.如果G是有向图,那么连接v_i和v_j的路径中所有的边都必须同向.如果图中任意两点都是连通的,那么图被称作连通图.图的连通性是图的基本性质. 连通分量:无向图G的一个极大连通子图称为G的一个连通分量(或连通分支).连通图只有一个连通分量,即其自身:非连通的无向图有多个连通分量. 初级通路:通路中所有的顶点互不相同.初级通路必为简单通路,但反之不真. 强连通

C#与数据结构--图的遍历

C#与数据结构--图的遍历 8.2 图的存储结构 图 的存储结构除了要存储图中各个顶点的本身的信息外,同时还要存储顶点与顶点之间的所有关系(边的信息),因此,图的结构比较复杂,很难以数据元素在存储区 中的物理位置来表示元素之间的关系,但也正是由于其任意的特性,故物理表示方法很多.常用的图的存储结构有邻接矩阵.邻接表.十字链表和邻接多重表. 8.2.1  邻接矩阵表示法 对于一个具有n个顶点的图,可以使用n*n的矩阵(二维数组)来表示它们间的邻接关系.图8.10和图8.11中,矩阵A(i,j)=1

数据结构--图 的JAVA实现(上)

1,摘要: 本系列文章主要学习如何使用JAVA语言以邻接表的方式实现了数据结构---图(Graph),这是第一篇文章,学习如何用JAVA来表示图的顶点.从数据的表示方法来说,有二种表示图的方式:一种是邻接矩阵,其实是一个二维数组:一种是邻接表,其实是一个顶点表,每个顶点又拥有一个边列表.下图是图的邻接表表示. 从图中可以看出,图的实现需要能够表示顶点表,能够表示边表.邻接表指是的哪部分呢?每个顶点都有一个邻接表,一个指定顶点的邻接表中,起始顶点表示边的起点,其他顶点表示边的终点.这样,就可以用邻

数据结构-图

1.图的定义 图:是一种灵活的数据结构,一般作为一种模型用来定义对象之间的关系或者联系.对象由顶点表示,而对象之间的关系或关联则通过顶点之间的边来表示. 2.图的应用 图算法.统计网络跳数.拓扑排序.图着色.哈密顿圈问题.分团问题.可序列化冲突 3.图的代码实现 /*graph.h*/ #ifndef GRAPH_H #define GRAPH_H #include <stdlib.h> #include "list.h" #include "set.h"

数据结构--图 的JAVA实现(下)

在上一篇文章中记录了如何实现图的邻接表.本文借助上一篇文章实现的邻接表来表示一个有向无环图. 1,概述 图的实现与邻接表的实现最大的不同就是,图的实现需要定义一个数据结构来存储所有的顶点以及能够对图进行什么操作,而邻接表的实现重点关注的图中顶点的实现,即怎么定义JAVA类来表示顶点,以及能够对顶点进行什么操作. 为了存储图中所有的顶点,定义了一个Map<key, value>,实际实现为LinkedHashMap<T, VertexInterface<T>>,key 为

数据结构--图--图的数组存储表示,深度优先搜索遍历和广度优先搜索遍历

图有四种存储结构:数组,邻接表,十字链表,邻接多重表.下面以数组为存储结构来实现图的深度优先搜索遍历和广度优先搜索遍历.其中广度优先搜索遍历中有用到STL中的queue,注意头文件的包含.具体代码如下: //图的数组(邻接矩阵)存储表示和深度优先遍历 const int MAX_VERTEX_NUM=20; //最大顶点数 typedef enum {DG,DN,UDG,UDN} GraphKind ;//(有向图,有向网,无向图,无向网) typedef int VRType; typedef

数据结构--图--最小生成树(Prim算法)

构造连通网的最小生成树,就是使生成树的边的权值之和最小化.常用的有Prim和Kruskal算法.先看Prim算法:假设N={V,{E}}是连通网,TE是N上最小生成树中边的集合.算法从U={u0}(uo属于V),TE={}开始,重复执行下述操作:在所有u属于U,v属于V-U的边(u,v)属于E中找到代价最小的一条边(u0,v0)并入集合TE,同时v0并入U,直至U=V为止.此时TE中必有n-1条边,T={V,{TE}}为N的最小生成树.为实现此算法,需另设一个辅助数组closedge,以记录从U

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

数据结构-图存储表示之邻接表

邻接表 在图论中,邻接表代表一个图中的所有边或弧. 邻接表存储表示,需要保存一个顺序存储的顶点表和每个顶点上的边的链接表. 邻接表(Adjacency List),即数组与链表相结合的存储方法. 如果是无向图,那么每条边由两个结点组成,分别代表边的两个端点: 如果是有向图,那么每条边是一个结点对,分别代表边的始点和终点. 一般来说,邻接表是无向的. 在计算机科学中,邻接表描述一种紧密相关的数据结构,用于表征图.在邻接表的表示中,对于图中的每个顶点,我们将保存所有其它与之相连的顶点(即"邻接表&q

数据结构——图

图(Graph) (参考资料:<大话数据结构><算法导论>) 图是由顶点的有穷非空集合和顶点之间的边的集合组成,通常表示为:G(V,E),其中G表示一个图,V是图G中顶点(Vertex)的集合,E是图中边的集合. 图的相关术语 1.无向图与有向图 无向图:图中任意两个顶点u和v之间的边没有方向(无向边),每一条无向边用无序偶对(u,v)或(v,u)表示. 无向完全图:任意两个顶点之间都存在边,边个数:n*(n-1)/2(n个顶点). 有向图:图中任意两个顶点u和v之间的边具有方向(