临接矩阵m

邻接矩阵是一个表示图中顶点之间连接关系的矩阵。对于一个无向图或有向图,邻接矩阵是一个方阵,其行和列代表图中的顶点,矩阵中的元素表示顶点之间的连接情况。
无向图的邻接矩阵
对于无向图,如果顶点i和顶点j之间有边相连,则邻接矩阵中第i行第j列(同时第j行第i列,因为是无向图)的元素为1,否则为0。
例子: 考虑一个无向图,包含4个顶点和以下边:
顶点A和顶点B之间有边
顶点A和顶点C之间有边
顶点B和顶点D之间有边
顶点C和顶点D之间有边
这个图的邻接矩阵如下:
A B C D
A 0 1 1 0
B 1 0 0 1
C 1 0 0 1
D 0 1 1 0
解释:
第一行第二列的1表示A和B之间有边。
第二行第一列的1表示B和A之间有边(因为是无向图,所以A和B之间的边是双向的)。
以此类推,其他位置的1表示相应的顶点之间有边。
有向图的邻接矩阵
对于有向图,邻接矩阵中的元素表示从一个顶点到另一个顶点的有向边。如果顶点i到顶点j有一条有向边,则邻接矩阵中第i行第j列的元素为1,否则为0。
例子: 考虑一个有向图,包含4个顶点和以下边:
顶点A指向顶点B
顶点A指向顶点C
顶点B指向顶点D
顶点C指向顶点D
这个图的邻接矩阵如下:
A B C D
A 0 1 1 0
B 0 0 0 1
C 0 0 0 1
D 0 0 0 0
解释:
第一行第二列的1表示A指向B。
第二行第四列的1表示B指向D。
以此类推,其他位置的1表示相应的有向边。
邻接矩阵是图论中描述图结构的一种常用方法,它可以用来快速判断两个顶点之间是否有边相连,以及进行图的各种算法分析。

以下是实现要求的代码: ``` #include <iostream> #include <fstream> #include <vector> using namespace std; class Graph { private: int** m_AdjMat; // 邻接矩阵 vector<vector<int>> m_AdjList; // 邻接表 int m_NumVertex; // 顶点数 int m_NumEdge; // 边数 public: Graph() { m_NumVertex = 0; m_NumEdge = 0; m_AdjMat = nullptr; m_AdjList.clear(); } ~Graph() { if (m_AdjMat != nullptr) { for (int i = 0; i < m_NumVertex; i++) { delete [] m_AdjMat[i]; } delete [] m_AdjMat; } m_AdjList.clear(); } Graph(string filepath) { ifstream fin(filepath); if (!fin) { cout << "File not found." << endl; exit(1); } fin >> m_NumVertex >> m_NumEdge; // 读入顶点数和边数 m_AdjMat = new int*[m_NumVertex]; for (int i = 0; i < m_NumVertex; i++) { m_AdjMat[i] = new int[m_NumVertex]; for (int j = 0; j < m_NumVertex; j++) { m_AdjMat[i][j] = 0; // 初始化邻接矩阵 } } m_AdjList.resize(m_NumVertex); // 初始化邻接表 int u, v; for (int i = 0; i < m_NumEdge; i++) { // 读入边 fin >> u >> v; m_AdjMat[u][v] = m_AdjMat[v][u] = 1; // 更新邻接矩阵 m_AdjList[u].push_back(v); // 更新邻接表 m_AdjList[v].push_back(u); } fin.close(); } bool isConnected() { // 判断连通图 vector<bool> visited(m_NumVertex, false); dfs(0, visited); for (bool v : visited) { if (!v) { return false; } } return true; } bool isEulerian() { // 判断欧拉图 if (!isConnected()) { return false; } for (int i = 0; i < m_NumVertex; i++) { if (m_AdjList[i].size() % 2 != 0) { return false; } } return true; } bool isHamiltonian() { // 判断哈密顿图 vector<int> path; vector<bool> visited(m_NumVertex, false); for (int i = 0; i < m_NumVertex; i++) { path.clear(); visited.clear(); visited.resize(m_NumVertex, false); if (dfs_path(i, i, visited, path)) { return true; } } return false; } private: void dfs(int u, vector<bool>& visited) { // 深度优先搜索 visited[u] = true; for (int v = 0; v < m_NumVertex; v++) { if (m_AdjMat[u][v] && !visited[v]) { dfs(v, visited); } } } bool dfs_path(int u, int start, vector<bool>& visited, vector<int>& path) { // 查找哈密顿路径 visited[u] = true; path.push_back(u); if (path.size() == m_NumVertex) { if (m_AdjMat[u][start]) { return true; } path.pop_back(); visited[u] = false; return false; } for (int v : m_AdjList[u]) { if (!visited[v]) { if (dfs_path(v, start, visited, path)) { return true; } } } path.pop_back(); visited[u] = false; return false; } }; ``` 使用方法: - 默认构造函数:`Graph g;` - 从文件构造:`Graph g("filename.txt");` - 判断连通图:`bool connected = g.isConnected();` - 判断欧拉图:`bool eulerian = g.isEulerian();` - 判断哈密顿图:`bool hamiltonian = g.isHamiltonian();`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值