zoukankan      html  css  js  c++  java
  • DS博客作业06--图

    1.思维导图及学习体会

    1思维导图

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

    • 1. 在我看来,图就是一堆顶点和边的集合,既然是图可以分为有向图和无向图、还可以分为连通图和非连通图。在图结构中,每个元素可以有零个或多个前驱元素,也可以有零个或多个后继元素,也就是说元素之间的关系是多对多的。图的存储方法有邻接矩阵和邻接表,邻接矩阵顾名思义,是一个矩阵,存储着边的信息的矩阵,而顶点则用矩阵的下标表示,如果是无向图则有A [j ,i] = A[i, j],所以无向图的邻接矩阵是一个对称矩阵;但如果是有向图,则不一定是一个对称矩阵。邻接表可以有效避免内存的浪费,邻接表用一个一维数组存储顶点,利用邻接表建图时候,需要创建多个结构体,如结点类型的结构体,头结点也弄一个结构体,还有邻接表一个结构体。两种不同的存储有各自的优缺点,适用于不同的地方。如果是稀疏图或者需要特定用途的话采用领阶矩阵存储结构的好,反之如果是需要插入删除等操作的话采用邻接表的好。
    • 2.图的遍历有广度优先遍历BFS和深度优先遍历DFS,不过书上给两种算法的代码对应的都是针对于连通图的算法,还有最小生成树的算法有prim算法和克鲁斯卡尔算法,克鲁斯卡尔算法的时间复杂度与边e有关,克鲁斯卡尔算法时间复杂度O(e2),prim算法时间复杂度与图的顶点n数有关,其时间复杂度为O(n2)。还有求最短路径的算法:Dijkstra和Floyd算法,虽然Floyd算法更精短,但真是理解不来,时间复杂度也不少O(n^3),按老师所说的还算不错了。
    • 3.图的话结构体多了很多,光是要记住的类型名也很多,因为结构体多,所以有时候在调用一些结构体里的数据时就容易搞错,也因为Devc有时候不能够像vs那样直接显示结构体里包含的成员,所以这段时间也改用vs来编写代码了,这次pta上的题目大都可以看书本上的代码来写,或改进些

    2.PTA实验作业

    2.1.题目1:7-3 六度空间

    “六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图1所示。
    “六度空间”理论虽然得到广泛的认同,并且正在得到越来越多的应用。但是数十年来,试图验证这个理论始终是许多社会学家努力追求的目标。然而由于历史的原因,这样的研究具有太大的局限性和困难。随着当代人的联络主要依赖于电话、短信、微信以及因特网上即时通信等工具,能够体现社交网络关系的一手数据已经逐渐使得“六度空间”理论的验证成为可能。
    
    假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。
    
    

    2.1.1设计思路(伪代码)

    宏定义邻接矩阵g[10001][10001],顶点数v,边数e,循环变量i,中间变量x,y用来输入
    main函数
       定义浮点型数据 n,m来求最后所占比率
       输入顶点数v和边数e
       while e--   //构建邻接矩阵
            输入边关系 x y
            g[x][y] = g[y][x] = 1
       end while
       for i=1 to v do
            n=v  
            m=bfs(i) //调用bfs函数
       end for
       return 0
    
    int bfs(int z)
       定义数组vis[10001]=0 表示是否被访问过的结点
       定义 last = z表示记录每层的最后一个元素
       i定义tail表示用于记录每一层压入栈时的结点
       定义 level = 0 表示与该结点距离是否为6
       定义count=1//表示结点
       创建int型栈q并入栈z
       将vis[z]置为1表示访问过了
       while q不为空 
          	z = q.front()//取栈顶元素于z
    	q.pop()//去栈顶
    	for i = 1to v do //广度遍历方法
    		if g[z][i] 等于1 并且 vis[i]等于 0 then
    				count++;
    				vis[i] = 1;
    				q.push(i);
    				tail = i;
    		end if 
             end for 
    	if last 等于z then//一层全部从栈弹出,准备开始弹下一层,弹出的数等于当前层最后一个元素,并记录与last 
    		level++;
    		last = tail;//记录最后一个元素 
            end if 
    		if  level 等于 6 break //符合题意的路径节点       
        return count
    
    

    2.1.2代码截图

    2.1.3本题PTA提交列表说明。

    • Q1:起初以为这是深度遍历问题,想的是与这个结点距离为6,那么便从起点出发,一旦找到长度6的顶点便返回
    • A1:然后试了好几次测试样例都是错的,问了舍友才知道应该用广度遍历,广度遍历的话找与起点有联系的点,并以此扩散,这样可以找到全部符合题意的点,而不是像深度遍历一样只能找一路
    • Q2:知道深度遍历行不通,就将函数题的邻接矩阵广度遍历拿来用,再慢慢改动点
    • A2:基本就是重写代码了,一堆宏定义都是是舍友教的,从编译错误那里开始就改成了广度遍历法
    • Q3:提交pta,发现还是不对,输出出来的结果比起答案少很多
    • A3:在遍历中,我没有对一旦level等于6就退出循环,导致最后结果比起来少了很多

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

    现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
    

    2.2.1设计思路(伪代码)

    宏定义无穷大INF为32767 及 MAXV 为1001
    宏定义邻接矩阵 g[MAXV][MAXV]以及数组 visited[MAXV]={0};
    定义 count 为1来判断是否为符合要求
    int main()
    {
            定义 i,n,e分别表示循环变量、顶点数、边数 
            定义浮点型数据 sum为成本
    	输入 n,e //顶点数 边数 
    	if  n-1大于e then  //不符合的情况 
    		输出-1
    		return 0
    	end if 
         CreateGraph(n, e)//建图函数
         sum=Prim(n,1)//计算最低成本 调用prim函数 
        if count==n then 
    	输出sum
    	else	输出-1
       end if 
    	return 0
    }
    
    void CreateGraph(int n, int e) //创建邻接矩阵
    {
    	定义 i,j,a, b, c;
    	for i = 0 to n; do//初始化
    		for j = 0 to n do
    			g[i][j]==0
                     end for
          end for
    	for i = 1 to e do
    	      输入 a,b,c
    	    g[a][b] =g[b][a]= c;
           end for
    }
    
    int Prim(int n, int v)
    {
            定义 数组 lowcost[MAXV],close[MAXV], cost = 0表示最低成本, i, j表示循环变量 min为最低的费用,index用来存下标
    	for i = 1 to n //给lowcost数组和close数组置初值 
    		lowcost[i] = g[v][i];
    		close[i] = v; 
    	end for
    	for i = 1 to n  do
    		min = INF
    		定义 flag=0//用来判断这一层是否有最低费用
    		for j = 1to n //从剩下的城市中找最近的点 
    			if lowcost[j] 不等于 0且lowcost[j] 小于 min)  then //计算费用最低 
    			     min = lowcost[j];
    			     index = j;
    			     flag=1;
    			end if 
    		end for 
    		if flag不为0 then //该层有最低费用
    			cost += min;
    			count++;
    		end if 
    		lowcost[index] = 0;
    		for j=1to n do  //进行调整 		
    			if lowcost[j] 不等于 0且g[index][j]小于lowcost[j then//修改数组的值 			
    				lowcost[j] = g[index][j];
    				close[j] = index;
    			end if 
    		end for
    	end for
    	return cost;
    }
    
    

    2.2.2代码截图


    2.2.3本题PTA提交列表说明。

    • Q1:如果无法畅通的情况处理不来
    • A1:后来在每次循环时候将最小min等于无穷大INF,如果最小的路径等于无穷大,则说明没有路径即无法正常畅通。
    • Q2:一开始是看书上的prim算法写的,没怎么改动,主要是那个最低费用的一开始不知道怎么写,然后先试着提交一下还是有分的
    • A2:后来我就设了min和index分别来存最少的路费和对应的点,并通过最后求一行的cost来计算最低费用
    • Q3:最后在第一层循环内有个地方错误
    • A3:就是要在每次要将index所在第一行初始化,就是lowcost[index]要置为0,否则会错误,不能跳进循环

    2.3.题目1:7-1 图着色问题

    图着色问题是一个著名的NP完全问题。给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色?
    
    但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。
    

    2.3.1设计思路(伪代码)

    
    宏定义数组 visited[501]={0},d[501],k=0
    宏定义邻接矩阵a[501][501]及循环变量与一些变量:v,e,z,x,y,i,j,n;
    void dfs(int i)
    {
           定义 j;
           d[k++]=i;
           visited[i]=1;
           forj=1to v do       
               if(a[i][j]等于1 并且 visited[j]等于0 then dfs(j);
               end if
           end for
    }
    void dfs1()
    {
        定义 i;
        for i=1 to v
        
             if visited[i]等于0 then dfs(i); //没被访问过
        end for
    }
    
    int main()
    {
        输入v、e、z;
        for i=0 to e
        
          输入变关系x、y;
          a[x][y]=a[y][x]=1;
        end for
        dfs1();
        输入n;
        while n--
       
         初始化 b[501]={0},c[501],e[501],sum=0,flag=1;
         for i=1 to v;i++)
         
            输入c[i];
            b[c[i]]++;
            if b[c[i]]等于1 then sum++;
         end for 
         if sum不等于z then flag=0;
         end if
         for i=0 to k do e[i]=c[d[i]]
         end for
         for i=0 to k
         
             forj=0 to k     
            if a[d[i]][d[j]]等于1并且e[i]等于e[j] then
           
                flag=0;
                break;
           end if 
           
            if flag等于0 then break;
        end for 
         if flag等于0 输出No
         else 输出Yes
         end if 
    end while  
     return 0
    }
    
    
    

    2.3.2代码截图




    2.3.3本题PTA提交列表说明。

    • Q1:一开始提交中只有最小图和最大图正确
    • A1:在修改好多次后还是没能得到测试样例的正确答案,最后实在是写不动了,让舍友教我,然后才会写的
    • Q2:舍友说这道题是广度遍历...我写的是深度遍历
    • A2:主要是通过dfs的递归调用来实现遍历,本来我是写的是广度遍历的,因为自己画图的时候自己是有点像广度遍历那样,所以再写代码时候就以为用深度遍历,然后越搞越复杂,写了百来行代码,还搞不出来

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

    3.1.1截图错题代码:6-2 jmu-ds-图邻接表操作

    错误

    3.2 错的原因及处理方法

    深度遍历时候,指针指向下一个的时候,考试时候想错了,然后放在了如果没被遍历过的if语句中,导致超时,将语句放在if语句外就可以了
    

    3.2.1截图错题代码:6-3 jmu-ds-拓扑排序

    错误


    3.2 错的原因及处理方法

    改正



    可能是考试时候打得太快了...把大写G写成了小写g,while也写错了,写成了whlie...
    

    3.1.1截图错题代码:7-1 六度空间

    错误

    3.2 错的原因及处理方法

    忘记用tail记录下每行的最后一个没被遍历的数,还有当时看题目搞错题目意思了,以为少于6是当等于7时候退出循环,主要是考试前特别慌这最后一场考试,经常去写去看这些pta代码,基本到最后都快能背下来了,连变量名都没换
    

    3.1.1截图错题代码:7-2 公路村村通

    错误


    3.2 错的原因及处理方法

    忘记考虑了另外就是当数目不对时候也是不符合的情况,也要输出-1,还有就是之前不好理解的将最后一个没被遍历的那一行的首个置为0,在考试时候还是没注意到,又忘记了,最后还是没时间就没去细想了
    
  • 相关阅读:
    终极解决VS2015 安装失败问题,如 安装包损坏或丢失
    解决vmware安装 win7 后 没有虚拟网卡驱动 不能上网的问题
    WIN10 64位下VS2015 MFC直接添加 halcon 12的CPP文件实现视觉检测
    linux操作系统-两台linux服务器SSH免密码登录
    linux操作系统-设置静态ip
    mysql学习-windows下绿色版mysql安装问题解决办法
    Svn Server 强制提交者输入注释信息
    spingmvc项目根路径访问不到
    python进阶12 Redis
    python进阶11 正则表达式
  • 原文地址:https://www.cnblogs.com/zwl-/p/10962649.html
Copyright © 2011-2022 走看看