使用C++实现有向图的邻接矩阵,以及可达矩阵的计算算法。 请完成Project05.cpp中DirectedGraph类的成员函数,具体要求如下: DirectedGraph类: 用来表示一个有向图。 成员变量: m_AdjMat:邻接矩阵 m_ReachabilityMat:可达矩阵 成员函数: DirectedGraph():默认构造函数,构造一个空图。 ~DirectedGraph():析构函数 DirectedGraph(string filepath):解析文件filepath,构造一个DirectedGraph对象。 filepath文件格式与项目四相同,但本项目的图为有向图。 DirectedGraph(const Graph & graph):复制构造函数 operator=(const Graph & graph):赋值运算符 ClearGraph():清空图的邻接矩阵和可达矩阵。 OutputGraph():输出图的邻接矩阵 operator*(const DirectedGraph & graph): 乘法运算符,用于实现可达矩阵运算中的矩阵逻辑乘 DirectedGraph Pow(int power):邻接矩阵的整数次幂。 用法如下: DirectedGraph a; a = a.Pow(5); 即a的5次幂,相当于a = a * a * a * a * a; 注意要考虑0次幂的情况。 该函数适合以递归实现。 DirectedGraph MatOr(DirectedGraph graph):矩阵逐元素的逻辑或运算。 例如: 1 0 0 1 与 0 1 1 0 运算后的结果为 1 1 1 1 void CalcReachabilityMat():计算可达矩阵,要求该函数基于*运算符和Pow函数实现 void OutputReachabilityMat():输出可达矩阵 IsConnected(int src, int dst):基于可达矩阵判断从节点src与dst之间是否存在通路,如存在返回真,否则返回假
时间: 2024-02-17 07:01:48 浏览: 166
根据题目要求,以下是实现DirectedGraph类的代码。其中,可达矩阵的计算基于矩阵乘法和邻接矩阵的整数次幂运算。
```cpp
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
class DirectedGraph {
public:
vector<vector<int>> m_AdjMat; // 邻接矩阵
vector<vector<int>> m_ReachabilityMat; // 可达矩阵
// 默认构造函数,构造一个空图
DirectedGraph() {}
// 析构函数
~DirectedGraph() {}
// 解析文件filepath,构造一个DirectedGraph对象
DirectedGraph(string filepath) {
ifstream infile(filepath);
if (!infile.is_open()) {
cout << "Error opening file " << filepath << endl;
return;
}
string line;
getline(infile, line);
istringstream iss(line);
iss >> m_VerticesCount >> m_EdgesCount;
// 初始化邻接矩阵和可达矩阵
m_AdjMat.resize(m_VerticesCount);
m_ReachabilityMat.resize(m_VerticesCount);
for (int i = 0; i < m_VerticesCount; i++) {
m_AdjMat[i].resize(m_VerticesCount);
m_ReachabilityMat[i].resize(m_VerticesCount);
}
// 读入边
while (getline(infile, line)) {
istringstream iss(line);
int u, v;
iss >> u >> v;
m_AdjMat[u][v] = 1;
}
infile.close();
}
// 复制构造函数
DirectedGraph(const DirectedGraph & graph) {
m_VerticesCount = graph.m_VerticesCount;
m_EdgesCount = graph.m_EdgesCount;
m_AdjMat = graph.m_AdjMat;
m_ReachabilityMat = graph.m_ReachabilityMat;
}
// 赋值运算符
DirectedGraph & operator=(const DirectedGraph & graph) {
m_VerticesCount = graph.m_VerticesCount;
m_EdgesCount = graph.m_EdgesCount;
m_AdjMat = graph.m_AdjMat;
m_ReachabilityMat = graph.m_ReachabilityMat;
return *this;
}
// 清空图的邻接矩阵和可达矩阵
void ClearGraph() {
m_VerticesCount = 0;
m_EdgesCount = 0;
m_AdjMat.clear();
m_ReachabilityMat.clear();
}
// 输出图的邻接矩阵
void OutputGraph() const {
for (int i = 0; i < m_VerticesCount; i++) {
for (int j = 0; j < m_VerticesCount; j++) {
cout << m_AdjMat[i][j] << " ";
}
cout << endl;
}
}
// 矩阵乘法,用于实现可达矩阵运算中的矩阵逻辑乘
DirectedGraph operator*(const DirectedGraph & graph) const {
DirectedGraph result;
result.m_VerticesCount = m_VerticesCount;
result.m_EdgesCount = m_EdgesCount;
result.m_AdjMat.resize(m_VerticesCount);
result.m_ReachabilityMat.resize(m_VerticesCount);
for (int i = 0; i < m_VerticesCount; i++) {
result.m_AdjMat[i].resize(m_VerticesCount);
result.m_ReachabilityMat[i].resize(m_VerticesCount);
for (int j = 0; j < m_VerticesCount; j++) {
result.m_AdjMat[i][j] = m_AdjMat[i][j] && graph.m_AdjMat[i][j];
result.m_ReachabilityMat[i][j] = m_ReachabilityMat[i][j] || graph.m_ReachabilityMat[i][j];
}
}
return result;
}
// 邻接矩阵的整数次幂
DirectedGraph Pow(int power) const {
DirectedGraph result(*this);
if (power == 0) {
// 返回单位矩阵
for (int i = 0; i < m_VerticesCount; i++) {
for (int j = 0; j < m_VerticesCount; j++) {
result.m_AdjMat[i][j] = (i == j ? 1 : 0);
}
}
} else if (power > 1) {
result = result.Pow(power / 2);
result = result * result;
if (power % 2 == 1) {
result = result * (*this);
}
}
return result;
}
// 矩阵逐元素的逻辑或运算
DirectedGraph MatOr(const DirectedGraph & graph) const {
DirectedGraph result(*this);
for (int i = 0; i < m_VerticesCount; i++) {
for (int j = 0; j < m_VerticesCount; j++) {
result.m_AdjMat[i][j] = m_AdjMat[i][j] || graph.m_AdjMat[i][j];
}
}
return result;
}
// 计算可达矩阵
void CalcReachabilityMat() {
m_ReachabilityMat = m_AdjMat.Pow(m_VerticesCount);
}
// 输出可达矩阵
void OutputReachabilityMat() const {
for (int i = 0; i < m_VerticesCount; i++) {
for (int j = 0; j < m_VerticesCount; j++) {
cout << m_ReachabilityMat[i][j] << " ";
}
cout << endl;
}
}
// 基于可达矩阵判断从节点src与dst之间是否存在通路
bool IsConnected(int src, int dst) const {
return m_ReachabilityMat[src][dst];
}
private:
int m_VerticesCount; // 节点数
int m_EdgesCount; // 边数
};
```
在上述代码中,我们定义了一个DirectedGraph类来表示有向图,其中包含了邻接矩阵和可达矩阵等成员变量,以及用于构造和操作有向图的各种成员函数。其中,CalcReachabilityMat函数基于矩阵乘法和邻接矩阵的整数次幂运算来计算可达矩阵,IsConnected函数基于可达矩阵判断从节点src与dst之间是否存在通路。
阅读全文