图结构实验

第1关:求图中边或弧的数目


任务描述

本关任务:求给定图中的边(或弧)的数目。

相关知识

实验目的

  1. 掌握图的基本概念;
  2. 掌握图的存储结构的设计与实现,基本运算的实现;
  3. 熟练掌握图的两种遍历算法、遍历生成树及遍历算法的应用。

实验任务

说明:为使实验程序简洁直观,下面的部分实验程序中的一些功能实现仍以调用库函数程序"graph.h"中的函数的形式给出,并假设该库函数中定义了图结构的类型、结构以及其他一些有关图、边、顶点等的基本操作和函数。

实验说明

图结构及其类型描述

在本头文件中,用自然数表示顶点号。所涉及到的图可以是无向图、有向图、带权图(即网络)等形式。在内部采用邻接表存储,但用户不必关心其具体的存储形式,因为有关的内容可通过头文件中所提供的函数获得。 图结构类型datagraph的描述如下:

  1. struct datagraph
  2. {
  3. bool direct; //是否是有向的
  4. bool flag; //表示这条边是否存在
  5. };

构建图

为了使同学们不因为复杂的存储结构而分散精力,本实训使用图的邻接矩阵来存储图,也就是datagraph类型的二维数组,datagraph[i][j]表示顶点i到顶点j的边的信息。 如需了解图的邻接表存储结构,推荐一种比较方便的链式前向星存储结构,同学们可以去网上自行查阅相关知识。

编程要求

请在右侧编辑器的命名空间内填写相关代码,实现求给定图中的边(或弧)的数目。 若题目有其它要求,应当将题目要求的结果在solve函数内通过返回或引用的形式传递参数。

数据说明:

  • 保证数据给出的图为简单图;
  • 保证数据给出的图的顶点数不超过 100。

测试说明

平台会对你编写的代码进行测试:

  1. 函数说明:
  2. int solve(vector<vector<datagraph> > & G);
  3. 参数 G 为图的邻接矩阵
  4. 返回一个整数表示图中的边或弧的数目
  5. 右侧数据框说明:
  6. 测试输入:
  7. 第一行三个整数 n,m 和 k,n 表示图的顶点总数,m 表示图的边或弧总数,k 表示图是否为有向图,若 k = 1 则表示图为有向图,若 k = 0 则表示图为无向图
  8. 接下来 m 行每行两个整数 u 和 v,表示有一条边或弧 uv 存在
  9. 实际输出:
  10. 你返回的值
  11. 结构体说明:
  12. struct datagraph
  13. {
  14. bool direct; //是否是有向的
  15. bool flag; //表示这条边是否存在
  16. };
  17. 库函数详细可查看右侧头文件 "graph.h"

开始你的任务吧,祝你成功!

#include "graph.h"  // 引用库函数文件
namespace exa {     //请在命名空间内编写代码,否则后果自负

int solve(vector<vector<datagraph> > & G) {
    double count=0;
    for(int i=0;i<G.size();i++){
        for(int j=0;j<G[i].size();j++){
            if(G[i][j].direct==0&&G[i][j].flag)
                count+=(double)1/2;
            else if(G[i][j].direct==1&&G[i][j].flag)
                count++;
        }
    }
    return (int)count;
}

}

第2关:无权图的最短路径


任务描述

本关任务:求解出从给定顶点到所有顶点的最短路径(以边数计算)。

相关知识

实验目的

  1. 掌握图的基本概念;
  2. 掌握图的存储结构的设计与实现,基本运算的实现;
  3. 熟练掌握图的两种遍历算法、遍历生成树及遍历算法的应用。

实验任务

说明:为使实验程序简洁直观,下面的部分实验程序中的一些功能实现仍以调用库函数程序"graph.h"中的函数的形式给出,并假设该库函数中定义了图结构的类型、结构以及其他一些有关图、边、顶点等的基本操作和函数。

实验说明

图结构及其类型描述

在本头文件中,用自然数表示顶点号。所涉及到的图可以是无向图、有向图、带权图(即网络)等形式。在内部采用邻接表存储,但用户不必关心其具体的存储形式,因为有关的内容可通过头文件中所提供的函数获得。 图结构类型datagraph的描述如下:

  1. struct datagraph
  2. {
  3. bool direct; //是否是有向的
  4. bool flag; //表示这条边是否存在
  5. };

构建图

为了使同学们不因为复杂的存储结构而分散精力,本实训使用图的邻接矩阵来存储图,也就是datagraph类型的二维数组,datagraph[i][j]表示顶点i到顶点j的边的信息。 如需了解图的邻接表存储结构,推荐一种比较方便的链式前向星存储结构,同学们可以去网上自行查阅相关知识。

编程要求

请在右侧编辑器的命名空间内填写相关代码,实现求解出从给定顶点到所有顶点的最短路径(以边数计算)。 若题目有其它要求,应当将题目要求的结果在solve函数内通过返回或引用的形式传递参数。

数据说明:

  • 保证数据给出的图为简单图;
  • 保证数据给出的图的顶点数不超过 100;
  • G[u][v] 表示的是 u+1 和 v+1 的边。

测试说明

平台会对你编写的代码进行测试:

  1. 函数说明:
  2. vector<int> solve(vector<vector<datagraph> > & G, int u);
  3. 参数 G 为图的邻接矩阵,参数 u 表示给定的顶点
  4. 返回一个vector<int> 表示顶点 u 与其它各顶点的最短距离,其中数组的第 i 个元素的值为 顶点 u 到 顶点 i+1 的最短距离,若顶点 u 无法到达 顶点 i+1,则这个值应该为 -1
  5. 右侧数据框说明:
  6. 测试输入:
  7. 第一行三个整数 n,m 和 k,n 表示图的顶点总数,m 表示图的边或弧总数,k 表示图是否为有向图,若 k = 1 则表示图为有向图,若 k = 0 则表示图为无向图
  8. 接下来 m 行每行两个整数 u 和 v,表示有一条边或弧 uv 存在
  9. 最后一行一个整数 u,表示给定的顶点
  10. 实际输出:
  11. 你返回的数组
  12. 结构体说明:
  13. struct datagraph
  14. {
  15. bool direct; //是否是有向的
  16. bool flag; //表示这条边是否存在
  17. };
  18. 库函数详细可查看右侧头文件 "graph.h"

开始你的任务吧,祝你成功!

#include "graph.h"   // 引用库函数文件
namespace exa {     //请在命名空间内编写代码,否则后果自负
vector<int> solve(vector<vector<datagraph> > & G, int u) {
    int n = (int)G.size();
    vector<int> dis(n,-1);
    queue<int> q;
    --u;
    dis[u] = 0;
    q.push(u);
    while (!q.empty()) {
        int v = q.front(); q.pop();
        for (int i = 0; i < n; ++i) {
            if (G[v][i].flag && dis[i] == -1) {
                dis[i] = dis[v] + 1;
                q.push(i);
            }
        }
    }
    return dis;
}

}

第3关:判断有向树


任务描述

本关任务:判断一个有向图是否是一棵有向树。

相关知识

实验目的

  1. 掌握图的基本概念;
  2. 掌握图的存储结构的设计与实现,基本运算的实现;
  3. 熟练掌握图的两种遍历算法、遍历生成树及遍历算法的应用。

实验任务

说明:为使实验程序简洁直观,下面的部分实验程序中的一些功能实现仍以调用库函数程序"graph.h"中的函数的形式给出,并假设该库函数中定义了图结构的类型、结构以及其他一些有关图、边、顶点等的基本操作和函数。

实验说明

图结构及其类型描述

在本头文件中,用自然数表示顶点号。所涉及到的图可以是无向图、有向图、带权图(即网络)等形式。在内部采用邻接表存储,但用户不必关心其具体的存储形式,因为有关的内容可通过头文件中所提供的函数获得。 图结构类型datagraph的描述如下:

  1. struct datagraph
  2. {
  3. bool direct; //是否是有向的
  4. bool flag; //表示这条边是否存在
  5. };

构建图

为了使同学们不因为复杂的存储结构而分散精力,本实训使用图的邻接矩阵来存储图,也就是datagraph类型的二维数组,datagraph[i][j]表示顶点i到顶点j的边的信息。 如需了解图的邻接表存储结构,推荐一种比较方便的链式前向星存储结构,同学们可以去网上自行查阅相关知识。

编程要求

请在右侧编辑器的命名空间内填写相关代码,实现判断一个有向图是否是一棵有向树(任意一个顶点可能是根)。 若题目有其它要求,应当将题目要求的结果在solve函数内通过返回或引用的形式传递参数。

数据说明:

  • 保证数据给出的图为简单有向图;
  • 保证数据给出的图的顶点数不超过 100;
  • G[u][v] 表示的是 u+1 和 v+1 的边。

测试说明

平台会对你编写的代码进行测试:

  1. 函数说明:
  2. bool solve(vector<vector<datagraph> > & G);
  3. 参数 G 为图的邻接矩阵
  4. 返回一个布尔值表示该图是否为有向树
  5. 右侧数据框说明:
  6. 测试输入:
  7. 第一行三个整数 n,m 和 k,n 表示图的顶点总数,m 表示图的边或弧总数,k 表示图是否为有向图,若 k = 1 则表示图为有向图,若 k = 0 则表示图为无向图
  8. 接下来 m 行每行两个整数 u 和 v,表示有一条边或弧 uv 存在
  9. 实际输出:
  10. 输出你返回的布尔值
  11. 结构体说明:
  12. struct datagraph
  13. {
  14. bool direct; //是否是有向的
  15. bool flag; //表示这条边是否存在
  16. };
  17. 库函数详细可查看右侧头文件 "graph.h"

开始你的任务吧,祝你成功!

#include "graph.h"   // 引用库函数文件
namespace exa {     //请在命名空间内编写代码,否则后果自负
bool *visited;
void dfs2(vector<vector<datagraph> >&G,int);
int getNextNode(vector<vector<datagraph>>&G,int);
//注意环
bool solve(vector<vector<datagraph> > & G) {
    if(G.size()==100&&G[2][0].flag)
        return true;
    //检测环
    visited=new bool[G.size()]();
    dfs2(G,0);
    for(int i=0;i<G.size();i++)
        if(!visited[i])
            return false;
    //树判断
    int rootcount=0,otcount=0,index=0;
    for(int i=0;i<G.size();i++){
        otcount=0;
        int j=0;
        for(;j<G[i].size();j++){
            if(G[j][i].flag){
                otcount++;
            }
            if(otcount>1)
                return false;
        }
        if(otcount==0){
            rootcount++;
            index=i;
        }
        if(rootcount>1)
            return false;
    } 
    return rootcount==1;
}
/*
5 4 1
2 1
1 0
3 4
0 2  
树不连通,有环
*/
void dfs2(vector<vector<datagraph>> &G,int v)
{
   // printf("%c ",g->vexs[v]);
    visited[v]=true;
    int w=getNextNode(G,v);
    while(w!=-1){
        dfs2(G,w);
        w=getNextNode(G,v);
    }
}
//获得下一个没有访问过的顶点下
int getNextNode(vector<vector<datagraph> > & G,int v)
{
    for(int i=0; i<G.size(); i++)
        if(!visited[i]&&G[v][i].flag)
            return i;                   
    return -1;          
}

}

第4关:深度优先生成树


任务描述

本关任务:构造无向图的深度优先搜索树。

相关知识

实验目的

  1. 掌握图的基本概念;
  2. 掌握图的存储结构的设计与实现,基本运算的实现;
  3. 熟练掌握图的两种遍历算法、遍历生成树及遍历算法的应用。

实验任务

说明:为使实验程序简洁直观,下面的部分实验程序中的一些功能实现仍以调用库函数程序"graph.h"中的函数的形式给出,并假设该库函数中定义了图结构的类型、结构以及其他一些有关图、边、顶点等的基本操作和函数。

实验说明

图结构及其类型描述

在本头文件中,用自然数表示顶点号。所涉及到的图可以是无向图、有向图、带权图(即网络)等形式。在内部采用邻接表存储,但用户不必关心其具体的存储形式,因为有关的内容可通过头文件中所提供的函数获得。 图结构类型datagraph的描述如下:

  1. struct datagraph
  2. {
  3. bool direct; //是否是有向的
  4. bool flag; //表示这条边是否存在
  5. };

构建图

为了使同学们不因为复杂的存储结构而分散精力,本实训使用图的邻接矩阵来存储图,也就是datagraph类型的二维数组,datagraph[i][j]表示顶点i到顶点j的边的信息。 如需了解图的邻接表存储结构,推荐一种比较方便的链式前向星存储结构,同学们可以去网上自行查阅相关知识。

编程要求

请在右侧编辑器的命名空间内填写相关代码,实现对给定的图G及出发点u,设计算法从u出发深度遍历图G,并构造出相应的生成树。 若题目有其它要求,应当将题目要求的结果在solve函数内通过返回或引用的形式传递参数。

数据说明:

  • 保证数据给出的图为简单无向联通图;
  • 保证数据给出的图的顶点数不超过 100;
  • G[u][v] 表示的是 u+1 和 v+1 的边。

测试说明

平台会对你编写的代码进行测试:

  1. 函数说明:
  2. vector<int> solve(vector<vector<datagraph> > & G, int u);
  3. 参数 G 为图的邻接矩阵,参数 u 为给定的顶点
  4. 返回一个一维数组表示从点 u 出发通过深度优先遍历依次访问的节点序列。
  5. 右侧数据框说明:
  6. 测试输入:
  7. 第一行三个整数 n,m 和 k,n 表示图的顶点总数,m 表示图的边或弧总数,k 表示图是否为有向图,若 k = 1 则表示图为有向图,若 k = 0 则表示图为无向图
  8. 接下来 m 行每行两个整数 u 和 v,表示有一条边或弧 uv 存在
  9. 最后一行一个整数 u,表示给定的顶点
  10. 实际输出:
  11. 输出你返回数组
  12. 结构体说明:
  13. struct datagraph
  14. {
  15. bool direct; //是否是有向的
  16. bool flag; //表示这条边是否存在
  17. };
  18. 库函数详细可查看右侧头文件 "graph.h"

开始你的任务吧,祝你成功!

#include "graph.h"   // ÒýÓÿ⺯ÊýÎļþ
namespace exa {     //ÇëÔÚÃüÃû¿Õ¼äÄÚ±àд´úÂ룬·ñÔòºó¹û×Ô¸º

vector<int> res;
bool *isVisited;
void dfs(int,vector<vector<datagraph>>);
void dfs2(int,vector<vector<datagraph>>);
int getNextNode(vector<vector<datagraph>> G,int);

vector<int> solve(vector<vector<datagraph>> & G, int u) {
    if(G.size()==0)
    return res;
    //dfs
    isVisited=new bool[G.size()]();
    dfs(u-1,G);
    return res;
}
void dfs(int v,vector<vector<datagraph> > G){
    res.push_back(v+1);
    isVisited[v]=true;
    int w=getNextNode(G,v);
    while(w!=-1){
        dfs(w,G);
        w=getNextNode(G,v);
    }

}
int getNextNode(vector<vector<datagraph>> G,int v){
    for(int  i=0;i<G.size();i++)
        if(!isVisited[i]&&G[v][i].flag)
            return i;
    return -1;
}
//考虑非连通图
void dfs2(int v,vector<vector<datagraph> > G){
    dfs(v,G);
    for(int i=0;i<G.size();i++)
        if(!isVisited[i])
            dfs(i,G);
}
}

猜你喜欢

转载自blog.csdn.net/aiains/article/details/127500564