• DS博客作业06--图


    1.本周学习总结(0--2分)

    1.思维导图

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

    • 本周学习了图结构,图结构相对来说内容还是比较多的,但是相比较树我觉得其实更简单清晰一点 。主要图中很多算法包括如解决最小生成树问题的Prime、Kruskal算法,最短路径的Dijkstra、Floy算法等略微有点复杂,代码量也比较大。图与之前学习的树也有很大的联系。需要我们融汇贯通,课后认真巩固。
    • 图的储存结构分为邻接表和邻接矩阵,我觉得邻接矩阵更好用一点,结构体也比较简单。图形结构属于复杂的非线性数据结构,在实际应用中很多问题可以用图来描述。在图结构中,每个元素可以有零个或多个前驱元素,也可以有零个或多个后继元素,也就是说元素之间的关系是多对多的。无论多么复杂的图都是由顶点和边构成的,所以定义时,图结构由两个集合点和边构成。图的存储方法为邻接矩阵和邻接表,前者引用数组,后者引用指针,所以两者在不同算法上有着自己的优势。图的遍历分为广度优先遍历BFS和深度优先遍历DFS,当在一个不带权图中搜索从一个顶点到另一个顶点的一条路径时,DFS求出的路径不一定时最短路径,而BFS求出的路径一定是最短路径。

    2.2.题目1:7-1 图着色问题 (25 分)

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

    2.1.1设计思路

    
    int main()
    {
        MGraph g;
        定义color[502],flag=0,num=0;
        定义 v,e,k,n,i,j;
        输入 v,e,k;
        Create(g,v,e);//创建邻接矩阵
        输入方案个数n;
        while(n--)
        {
            int visited[502]={0};
            num=0;flag=0;
            for i=1 to i<=g.n
            {
                输入color[i];
                if(visited[color[i]]==0)
                {
                    visited[color[i]]=1;
                    num++;
                }
                end if
    	}
            end for
            if(num!=k)
            flag=1;
            for i=1 to i<=g.n
            for j=1 to j<g.n
            {
                if(g.edges[i][j]==1&&color[i]==color[j])
                {
                    flag=1;
                    break;
                }
                if(flag==1)
                break;
            }
            end for
            if(flag)	
            cout<<"No"<<endl;
    	else
    	cout<<"Yes"<<endl;
    	return 0;
    }
    
    void Create(MGraph &g,int v,int e)//建立邻接矩阵
    {
    	定义i,j,k;
    	定义 a,b;
    	定义vexs[500];
    	for i=1 to i<=v
    	vexs[i]=1;
    	for j=0 to j<e
    	{
    		输入 a,b;
    		g.edges[a][b]=1;
    		g.edges[b][a]=1;
    	}
            end for
    	g.e=e,g.n=v;	
    }
    
    

    2.1.2.代码截图




    2.1.3本题PTA提交列表说明。

    • Q1:没看清题目是必须方案中颜色个数与给定k相同,导致错误
    • A1:加入代码哦判断方案方案个数与k值,不同则输出错误
    • Q2:写这题的时候总是出现最大图的测试点过不去,猜测是范围不够大的原因
    • A2:将color[501]改为color[502]

    2.2.题目2:六度空间

    “六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图1所示。

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

    2.2.1设计思路(伪代码)

    定义全局变量 数组map[10001][10001];
    定义全局变量 count;
    int main()
    {
        定义 n,m;
        输入 n m;
        定义i,a,b;
        for i=0 to i<m
        {
            输入a,b;
            map[a][b]=1;
            map[b][a]=1;
        } //建邻接矩阵
        end  for
        for i=1 to i<=n
        {
            count=1;
            BFS(i,n);//广度遍历
            输出i:;
            定义浮点数 answer;
            answer=(float)count/n*100;
            输出answer;
        }
        end  for
    }
    
    void BFS(int x,int n)
    {
        定义变量 level=0;
        定义变量 last,tail;
        last=x;//存放该层的最后一个顶点
        定义数组 visited[10001]={0};
        visited[x]=1;
        定义队列 q;
        x进队列q;
        while(队列q不为空)
        {
            取队头元素
            q出队
            for j=1 to j<=n
            {
                if(visited[j]==0&&map[x][j]==1)
                {
                    visited[j]=1;
                    count++;
                    j进队q;
                    tail=j;
                }
                end if
            } 
            end for
            if(x==last)//为该层最后一个元素
            {
                level++;//层数加一
                last=tail;
            }
            end if
            if(level==6)
            {
                break; 
            }
            end if
            }
    }
    
    

    2.2.2代码截图



    2.2.3本题PTA提交列表说明。

    • 这题刚开始没有什么思路,后来老师在上课的时候说这道题用广度遍历做,加上找了一下这道题的代码,就自己按照思路和老师说的写了。其中模仿的网上的代码运用了tail和last控制层数,用last,tail分别记录当前层数的最后一个元素、下一层最后一个元素,从而控制层数在六层内。统计这些结点个数。当last等于队头元素时,表示进入下一层,level加一,last修改为tail,当level的值达到6,提前退出循环。

    2.3.题目3.公路村村通

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

    2.3.1设计思路

    int prim()
    {
    	fill(d,d+N,inf);
    	d[1]=0;
    	定义 ans=0;
    	for int i=1 to i<=n
    	{
    		定义 u=-1;
    		定义 min=inf;
    		for int j=1 to j<=n
    		{
    			if(vis[j]==false&&d[j]<min)
    			{
    				u=j;
    				min=d[j];
    			}
    		}
                    end for
    		if(u==-1)
    		return -1;
    		vis[u]=true;
    		ans+=d[u];
    		for int v=1 to  v<=n 
    		{
    			if(vis[v]==false&&G[u][v]!=inf&&G[u][v]<d[v])
    			d[v]=G[u][v];
    		 } 
                    end  for
    	} 
    	return ans;
     } 
    
    int main()
    {
        定义u,v,c;
        输入 n m;
        fill(G[0],G[0]+N*N,inf);
        for int i=1 to i<=m
        {
        	输入u v c;
        	G[u][v]=G[v][u]=c;
        }
        int ans=prim();
        if(ans==-1)
        cout<<"-1";
        else
        cout<<ans;
        end if
        return 0;
    
     }
    

    2.3.2代码截图



    2.3.3本题PTA提交列表说明

    • Q1:邻接矩阵的初始化不对
    • A1:模仿书上的prim算法,将min置为inf

    3、上机考试错题及处理办法(-2--2分)

    3.1.截图错题代码



    3.2 错的原因及处理方法

    • Q1:这是上机考最基本的一题,在考试的时候一直出现段错误,百思不得其解,然后就一直提交,一直段错误。。。头铁只想先把这题写出来,然后上机考就die...
    • A1:后来和之前在pta上写的代码仔细对比发现在创建邻接矩阵的时候,for循环从i=0 to i<g.n,但是此时g.n还没有置为n,所以一直段错误。但是devc上确能运行,当时考试的时候就更发现不了哪里错了。
  • 相关阅读:
    Android 4.2开发环境搭建
    ManagementFactory cannot be resolved
    html css鼠标样式,鼠标形状
    开普勒三定律
    Apache CXF简介
    C++学习基础八——重载输入和输出操作符
    C++学习基础七——深复制与浅复制
    C++学习基础六——复制构造函数和赋值操作符
    C++学习基础五之函数参数——形参
    C++学习基础四——顺序容器和关联容器
  • 原文地址:https://www.cnblogs.com/zyxaa/p/10962541.html
Copyright © 2020-2023  润新知