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上确能运行,当时考试的时候就更发现不了哪里错了。
 posted on 2019-06-02 12:36  张瑀鑫  阅读(237)  评论(0编辑  收藏  举报