邻接矩阵
# include<iostream>
using namespace std;
const int maxn = 1e3;
int graph[maxn][maxn];
void init(int n,int m) {
//邻接矩阵
for (int i = 1;i <= n;i++) {//图中的点从1开始
for (int j = 1;j <= n;j++) {
graph[i][j] = 0;
}
}
}
void build(int n, int m) {
//邻接矩阵的建立
for (int i = 0;i < m;i++) {
int x1, y1, c1;
cin >> x1 >> y1 >> c1;
graph[x1][y1] = c1;//有向图
//graph[x1][y1] = graph[y1][x1] = c1;//无向图
}
}
void print(int n, int m) {
//邻接矩阵的遍历输出
for (int i = 1;i <= n;i++) {//图中的点从1开始
for (int j = 1;j <= n;j++) {
if(graph[i][j]!=0)//为零则是无边的
cout << i << "->" << j << "==" << graph[i][j] << endl;
}
}
}
int main() {
int n, m;
cin >> n >> m;
init(n, m);
build(n,m);
print(n, m);
}
局限性:
- 仅限于点数小于一千时,否则二维数组的内存会爆。
- 不可存重边的权值,除非该数组存放是是几条重边
邻接表
链式前向星
# include<iostream>
using namespace std;
const int maxn = 1e4;
//链式前向星
struct edge {
int to;//存放下一个与之相连的结点
int next;//存放上一个与之相连结点的下标(在存放的过程中不断更新)
int val;//权值
}Edge[maxn];
int head[maxn]; //存放当前与下标相连的最后面的那个点的下标
void init(int n,int m) {
for (int i = 0;i < maxn;i++) {//此处很重要!!!!!
Edge[i].next = -1; //因为放的是下标,所有包含0那么此时初始化就需要从-1开始
head[i] = -1;
}
}int cnt = 0;
void add_(int x1,int y1, int c1) {
Edge[cnt].to = y1;
Edge[cnt].val = c1;
Edge[cnt].next = head[x1];//与x1相连的上一个结点的位置
head[x1] = cnt++;//更新与x1相连结点的位置
}
void print(int n, int m) {
for (int i = 1;i <= n;i++) {
for (int j = head[i];j != -1;j = Edge[j].next) {
cout << i << "->" << Edge[j].to << "==" << Edge[j].val << endl;
}
}
}
int main() {
int n, m;
cin >> n >> m;
init(n, m);
for (int i = 0;i < m;i++) {
int x1, y1, c1;
cin >> x1 >> y1 >> c1;
add_(x1,y1,c1);
}
print(n, m);
}
/*
粗俗的理解:相当于用静态的结构体数组模拟了vector的动态进程
vector是比较慢的,每一次内存大了需要进行动态的扩容,很耗时
head数组用来存放最终结点最后连接的那个邻接点的下标(记住存放的是下标,这也为后面访问一系列邻接点提供了头)
Edge结构体数组,中to是存放目前结点所连接的下一个结点,val存放的是这条边所带的权值,next 存放的是这个点在目前结点之前所连接的结点的下标,而这个下标是不断的在head中存放的,(因为在建图的过程中,head数组里面不断放入的是该节点的上一个邻接点的位置)
*/