2023 年 10 月 26 日,神舟十七号载人飞船发

2023 年 10 月 26 日,神舟十七号载人飞船发射取得圆满成功,再次彰显了中国航天事业的辉煌成就。载人航天工程是包含众多子工程的复杂系统工程,为了保证工程的有序开展,需要明确各子工程的前导子工程,以协调各子工程的实施。该问题可以简化、抽象为有向图的拓扑序列问题。已知有向图G 采用邻接矩阵存储,类型定义如下。

typedef struct //图的类型定义
{
int numVertices, numEdges;//图的顶点数和有向边数
char VerticesList[MAXV];//顶点表,MAXV为已定义常量
int Edge[MAXV][MAXV];//邻接矩阵
}MGraph;

请设计算法

int uniquely(MGraph G)

,判定G 是否存在唯一的拓扑序列,若是,则返回1,否则返回 0。要求如下。

(1)给出算法的基本设计思想。

(2)根据设计思想,采用C 或C++语言描述算法,关键之处给出注释。


答案

1)算法基本设计思想

建立图 G 各顶点的入度表indegree[]。选择入度为0的顶点 v,将v 的所有邻接点的入度减1,重复执行这个过程。若每次选中的入度为0的顶点有且仅有一个,且共进行了 G.numVertices 次,则意味着存在唯一的拓扑序列,返回 1,否则不存在拓扑序列,或者存在多个拓扑序列,返回0。

2)算法实现

int uniquely(MGraph g)
{
  // 表示每个顶点的入度
  int inDegrees[g.numVertices];
  for (int v = 0; v < g.numVertices; v++) {
    for (int i = 0; i < g.numVertices; i++) {
      inDegrees[v] += g.Edge[i][v];
    }
  }
 // 遍历 numVertices 轮,每一轮判断是否 有且仅有 唯一的入度为 0 的顶点
  for (int v = 0; v < g.numVertices; v++) {
    // 入度为 0 的顶点个数
    int count0 = 0;
    // 来记录这一轮入度为 0 的顶点编号
    int targetv = -1;
    for (int i = 0; i < g.numVertices; i++) {
      if (inDegrees[i] == 0) {
        targetv = i;
        count0++;
      }
    }
    // 不存在唯一的拓扑序列
    if (count0 != 1) {
      return 0;
    }
    // 进行入度修改
    for (int j = 0; j < g.numVertices; j++) {
      inDegrees[j] -= g.Edge[targetv][j];
    }
  }
  // 存在唯一的拓扑序列
  return 1;
}

题目信息

题号:7678
题型:简答题
难度:普通