小韦老师@神犇营-my1076-邻接表的使用
码猿编程教育:韦长英
题目:
描述
这个题目我们来练习邻接表的使用。给出一个包含有向图和无向图的混合图 G,图上有 n 个点和 m 条边,现在你需要使用邻接表来存储该混合图 G 并按格式输出邻接表。
输入
输入第一行为两个正整数 n 和 m (1 ≤ n, m ≤ 100),表示混合图上的 n 个点和 m 条 边。
接下来输入 m 行,每行输入三个整数 a, x, y (0 ≤ a ≤ 1,0 ≤ x, y < n),表示点 x 和点 y 之间有一条边。如果 a = 0,则表示该边为有向边,如果 a = 1,则表示该边为无向边。
输出
输出邻接表,输出 n 行,第 i 行表示第 i 个点连接边的情况,首先输出 i,接着输出 : ,然后输出点 i 能到达的所有点的编号,边关系中后出现的点先输出。每个整数前有一个空格,具体格式见样例。
输入样例
4 4
0 0 1
1 0 2
0 3 1
1 2 3
输出样例
0: 2 1
1:
2: 3 0
3: 2 1
题解:
思路
整体思路:
考查图用邻接表存储。用 vector 数组作为邻接表进行存储,然后枚举每个 vector,进行倒序输出即可。
主要步骤:
- 定义一个 vector 数组,作为邻接表存储图
const int N = 110;
vector<int> G[N];
- 输入 m 条边的信息:
int a, x, y;
for (int i = 0; i < m; i++) {
cin >> a >> x >> y;
if (a == 0) G[x].push_back(y); // a 为 0,是有向边
else { // a 为 1,是无向边
G[x].push_back(y);
G[y].push_back(x);
}
}
- 枚举每个顶点,先输出每个顶点的编号,枚举每个顶点 i 能到达的所有点,然后倒着输出目标点的编号:
for (int i = 0; i < n; i++) { // 枚举每个顶点
cout << i << ": "; // 先输出每个顶点的编号
// 记得将 G[i].size() 强制转化为 int 型
// 枚举每个顶点 i 能到达的所有点,输出目标点的编号
for (int j = (int)G[i].size() - 1; j >= 0; j--) {
cout << G[i][j] << " ";
}
cout << endl;
}
思考
1°如果将 vector 数组定义成局部的,会怎么样呢?
2°为什么要讲 vector 的 size( ) 函数将其强制转化为 int 型呢?
完整代码:
#include <bits/stdc++.h>
using namespace std;
// 定义一个 vector 数组,作为邻接表存储图
const int N = 110;
vector<int> G[N];
int main() {
int n, m; // 顶点数,边数
cin >> n >> m;
int a, x, y;
for (int i = 0; i < m; i++) {
cin >> a >> x >> y;
if (a == 0) G[x].push_back(y); // a 为 0,是有向边
else { // a 为 1,是无向边
G[x].push_back(y);
G[y].push_back(x);
}
}
for (int i = 0; i < n; i++) { // 枚举每个顶点
cout << i << ": "; // 先输出每个顶点的编号
// 记得将 G[i].size() 强制转化为 int 型
// 枚举每个顶点 i 能到达的所有点,输出目标点的编号
for (int j = (int)G[i].size() - 1; j >= 0; j--) {
cout << G[i][j] << " ";
}
cout << endl;
}
return 0;
}
我是小韦老师,企者不立,跨者不行,每天进步一点点。
欢迎大家多多交流,如果发现有错误,请多指正。有疑问的同学也可以留言评论或者发邮件。邮箱:weichangying_wcy@163.com