图的实现-通信网络
图的实现-通信网络
一、问题分析
【问题描述】
应用图的 ADT 的物理实现来解决图的应用问题。
某国的军队由 N 个部门组成,为了提高安全性,部门之间建立了 M 条通路,
每条通路只能单向传递信息,即一条从部门 a 到部门 b 的通路只能由 a 向 b 传
递信息。信息可以通过中转的方式进行传递,即如果 a 能将信息传递到 b,b 又
能将信息传递到 c,则 a 能将信息传递到 c。一条信息可能通过多次中转最终到
达目的地。
由于保密工作做得很好,并不是所有部门之间都互相知道彼此的存在。只
有当两个部门之间可以直接或间接传递信息时,他们才彼此知道对方的存在。
部门之间不会把自己知道哪些部门告诉其他部门。
v>
上图中给了一个 4 个部门的例子,图中的单向边表示通路。部门 1 可以将消息
发送给所有部门,部门 4 可以接收所有部门的消息,所以部门 1 和部门 4 知道
所有其他部门的存在。部门 2 和部门 3 之间没有任何方式可以发送消息,所以
部门 2 和部门 3 互相不知道彼此的存在。
现在请问,有多少个部门知道所有 N 个部门的存在。或者说,有多少个部
门所知道的部门数量(包括自己)正好是 N。
【输入形式】
输入的第一行包含两个整数 N, M,分别表示部门的数量和单向通路的数
量。所有部门从 1 到 N 标号。
接下来 M 行,每行两个整数 a, b,表示部门 a 到部门 b 有一条单向通路。
【输出形式】
输出一行,包含一个整数,表示答案。
【样例输入】
4 4
1 2
1 3
2 4
3 4
【样例输出】
2
【样例说明】部门 1 和部门 4 知道所有其他部门的存在。
要处理的数据是部门的数量及单项通路的数量和位置。
实现功能:计算有多少个部门知道所有部门的存在,即与所有的节点直接或者
间接相连的节点数有多少个。
结果显示:输出知道所有部门存在的部门数目。
二、数据结构和算法设计
1)
图的抽象数据类型设计:
数据对象:G(V,S)
2)
物理数据对象设计(不用给出基本操作的实现
数据关系:采用邻接矩阵存储图的元素。用队列存储实现 DFS 遍历过程。
基本实现:
初始化:void Init(int n)=0;
顶点数:int n()=0;
边数:int e()=0;
第一个临接顶点:int first(int v)=0;
下一个临接顶点:int next(int v,int w)=0;
建边:void setEdge(int v1,int v2,int wght)=0;
删除边:void delEdge(int v1,int v2)=0;
判断两点间是否有边:bool isEdge(int i,int j)=0;
取边的权值:int weight(int v1,int v2)=0;
返回顶点的标记值:char getMark(int v)=0;
标记顶点: void setMark(int v,int val)=0;
DFS 遍历:void DFS(int i)
3) 算法思想的设计
用队列存储图的元素,用深度优先搜索遍历,对相连的顶点标记为 1,同时记录边。对每一
个顶点进行相同的操作,直至遍历所有的顶点。
4) 请用题目中样例,基于所设计的算法,详细给出样例求解过程。
1
图的邻接矩阵记录边和顶点的信息
void setEdge(int v1,int v2,int wt)
{
if(wt<=0)
{
cout<<"Illegal weight value";
}
else
{
if(matrix[v1][v2]==0)
{
numEdge++;}
matrix[v1][v2]=wt;
}
}
2
深度优先搜索
void DFS(int i)
{
int v,w;
Q.push(i);
setMark(i,1);
while(Q.size()!=0)
{
v=Q.front();
Q.pop();
for(w=first(v);w<n();w=next(v,w))
{
if(getMark(w)==-1)
{set(i,w);
setMark(w,1);
Q.push(w);
}
}
}
}
3
计算联通所有顶点的顶点数
int Count()
{
int ct=0;
for(int i=0;i<numVertex;i++)
{
for(int j=0;j<numVertex;j++)
{
if(a[i][j]==0&&a[j][i]==1)
{
a[i][j]=1;
}
}
}
for(int i=0;i<numVertex;i++)
{
bool x=true;
for(int j=0;j<numVertex;j++)
{
if(a[i][j]!=1&&i!=j)
{x=false;
}
}
if(x==true)
{
ct++;
}
}
return ct;
}
5) 关键功能的算法步骤
1 DFS 深度优先搜索:将顶点元素压入队列,标记顶点为 1
2
若下一个顶点未被标记,将元素出队列。
3
这样一层一层遍历,直至所有顶点标记。
三、算法性能分析
1) setEdge()操作是对所有边进行记录,算法复杂度 O(|D|)
2) DFS()操作是对图的节点进行遍历,算法复杂度为 O(|V|)
3) 计算所有联通点的个数采用双层循环判断是否联通所有节点,算法复杂度为 O(|V|^2)

浙公网安备 33010602011771号