题目描述
给定一个 n n n 个顶点 m m m 条边的无向图。请以邻接矩阵和邻接表的形式输出这一张图。
具体请看洛谷B3643
题解
邻接矩阵
邻接矩阵的定义:
- 邻接矩阵是一个二维数组,大小为 n × n n \times n n×n,其中 n n n 是图的顶点数。
- 邻接矩阵的每个元素 a i , j a_{i,j} ai,j 表示顶点 i i i 和顶点 j j j 之间的边。
- 如果顶点 i i i 和顶点 j j j 之间有边,则 a i , j = 1 a_{i,j} = 1 ai,j=1;否则 a i , j = 0 a_{i,j} = 0 ai,j=0。
邻接矩阵的优点:
- 方便计算顶点之间的距离。
- 方便判断顶点之间是否存在边。
邻接矩阵的缺点:
- 占用内存大。
- 无法快速判断两个顶点之间是否存在边。
邻接表
邻接表的定义:
- 邻接表是一个数组,大小为 n n n,其中 n n n 是图的顶点数。
- 邻接表的每个元素是一个链表,表示顶点 i i i 的所有邻接顶点。
- 链表中的每个元素是一个二元组 ( j , w ) (j,w) (j,w),表示顶点 i i i 和顶点 j j j 之间有一条边,边的权重为 w w w。
邻接表的优点:
- 占用内存小。
- 方便快速判断两个顶点之间是否存在边。
邻接表的缺点:
- 无法快速计算顶点之间的距离。
- 无法判断两个顶点之间是否存在边。
根据这些,我们可以想到用vector做。
代码
#include <bits/stdc++.h> // 万能头
using namespace std;
const int MAXN = 10001;
int map1[MAXN][MAXN]; // 连接矩阵
vector<int> e[MAXN]; // 连接表
int n, m;
int main() {
cin >> n >> m; // n个节点, m条边
for(int i = 1; i <= m; i++){
int u, v; // u节点和v节点之间有一条边
cin >> u >> v;
e[u].push_back(v); // 节点n的邻接表中加入节点m
e[v].push_back(u); // 节点m的邻接表中加入节点n
map1[u - 1][v - 1] = 1; // 在u和v之间创建一条边
map1[v - 1][u - 1] = 1; // 由于是无向图,所以是对称的
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
cout << map1[i][j] << ' '; // 遍历输出
}
}
for(int i = 1; i <= n; i++) {
cout << e[i].size() << ' '; // 输出节点的度,也就是连接表的大小
sort(e[i].begin(), e[i].end()); // 按照顺序输出
for(unsigned int j = 0; j < e[i].size(); j++) {
cout << e[i][j] << ' ';
}
cout << endl;
}
return 0; // 结束程序
}