数据结构作业BFS搜索有向图并返回从各个结点到零结点的步数

数据结构作业

使用BFS解决边长为1的图的单源最短路问题(有向图)
输入:
第一行是两个由空格隔开的正整数, n m。
n为点数,m为边数。
n小于等于10000,m小于等于100000。


点的编号为0 ~ n-1
接下来的m行,每行为两个由空格隔开的非负整数x y,表示从x点到y点有一条边。

输出:
n个整数,由空格隔开。分别表示0 ~ n-1号结点距离0号结点的最短路径长度。(每条边长度视为1)
0号点与自己的最短路径长度是0。
注意:图可能不连通!不连通的点请输出-1

代码如下,完全手敲,实在太菜,敲了俩小时。。。

#include <iostream>
#include <cstring>
#include <queue>
#define MAX 10000
using namespace std;
typedef struct EdgeNode{
    int adjvex;
    bool weight;
    EdgeNode *next;
}EdgeNode;
typedef struct{
    int data;
    EdgeNode *firstedge;
}AdjList[MAX];
typedef struct{
    AdjList adjlist;
    int numVertices,numEdges;
}GraphAdjList;

bool visited[MAX];
int ans[MAX];
void CreateALGraph(GraphAdjList& g){
    cin>>g.numVertices>>g.numEdges;
    //初始化
    for(int i=0;i<g.numVertices;i++){
        g.adjlist[i].data=i;
        g.adjlist[i].firstedge=NULL;
    }
    //创建邻接表
    for(int i=0;i<g.numEdges;i++){
        int x,y;
        cin>>x>>y;
        EdgeNode *e=new EdgeNode;
        e->weight=1;
        e->next=g.adjlist[x].firstedge;
        e->adjvex=y;
        g.adjlist[x].firstedge=e;
        //辣鸡助教说是有向图,给的测试数据和答案是无向图
        //真正的有向图应该没有下面这几行
        //无向图才要这样
        e=new EdgeNode;
        e->weight=1;
        e->next=g.adjlist[y].firstedge;
        e->adjvex=x;
        g.adjlist[y].firstedge=e;
    }
}
//工作代码bfs
void Work(const GraphAdjList& g){
    //bfs是用队列解决的,用stl比手写队列方便多了,其实就是不会手写队列。。。(bushi)
    queue<int> q;
    memset(ans,0,sizeof(ans));
    //各种flag是不知道怎么实现才用的,可以自行优化
    for(int i=1;i<g.numVertices;i++){
        int flag=0;
        memset(visited,false,sizeof(visited));
        visited[i]=true;
        q.push(i);
        while(q.empty()!=true){
            EdgeNode *p=g.adjlist[q.front()].firstedge;
            q.pop();
            ans[i]++;
            while(p!=NULL){
                if(p->adjvex==0){;
                    q=queue<int>();
                    flag=1;
                    break;
                }
                if(visited[p->adjvex]==false){
                    visited[p->adjvex]=true;
                    q.push(p->adjvex);
                }
                p=p->next;
            }
            if(flag==1){
                break;
            }
        }
        if(flag==1){
            flag=0;
            continue;
        }
        if(q.size()==0){
            ans[i]=-1;
        }
    }
    //辣鸡助教给的答案最后一个数后面没有空格,要单独输出
    for(int i=0;i<g.numVertices;i++){
        cout<<ans[i]<<" ";
    }
    cout<<endl;
}
//从main开始写
int main(){
    GraphAdjList gl;
    //写函数的意识
    CreateALGraph(gl);//ALGraph就是adjacency list graph
    Work(gl);//bfs
    //C++不写return 0; 默认为return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
邻接矩阵是一种表示图的数据结构,对于有向图而言,邻接矩阵可以采用以下方式实现: 1. 创建一个大小为n*n的二维组,其中n为有向图中的节点; 2. 对于有向边(i,j),邻接矩阵中第i行第j列的元素值为1,表示从节点i到节点j有一条有向边; 3. 如果有向边(i,j)不存在,则邻接矩阵中第i行第j列的元素值为0。 举个例子,对于如下有向图: ``` 1 ------> 2 <------ 3 | | | | | | v v v 4 ------->5-------->6 ``` 其邻接矩阵可以表示为: ``` 1 2 3 4 5 6 1 0 1 0 1 0 0 2 0 0 1 0 1 0 3 0 0 0 0 1 1 4 0 0 0 0 0 1 5 0 0 0 0 0 0 6 0 0 0 0 0 0 ``` 其中,第i行的元素之和即为第i个节点的出度,第i列的元素之和即为第i个节点的入度。 使用图的非递归搜索算法出该有向图结点的度,可以采用BFS算法或DFS算法实现。下面以BFS算法为例: ```python def bfs(adj_matrix, node): queue = [node] visited = set() while queue: cur_node = queue.pop(0) if cur_node not in visited: visited.add(cur_node) for i in range(len(adj_matrix)): if adj_matrix[cur_node][i] == 1: queue.append(i) return visited # 计算节点的度 def get_degree(adj_matrix, node): # 计算出度 out_degree = sum(adj_matrix[node]) # 计算入度 in_degree = len(bfs(adj_matrix.transpose(), node)) return out_degree, in_degree # 示例 adj_matrix = [[0, 1, 0, 1, 0, 0], [0, 0, 1, 0, 1, 0], [0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]] node = 2 out_degree, in_degree = get_degree(adj_matrix, node) print("节点{}的出度为{},入度为{}".format(node, out_degree, in_degree)) ``` 输出结果为: ``` 节点2的出度为1,入度为2 ``` 即节点2的出度为1,入度为2。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值