邻接表
邻接表
在图的描述中,经常会用到邻接表,有时我们会用到邻接矩阵来保存图的边和权值等信息,但是这回产生\(N^2\)的空间复杂度,在数据量比较大的多数情况下,我们是无法存储的,所以这是就需要用到空间复杂度为\(N\)的邻接表来存储图。
存储
对于邻接表的存储方式,我们除了保存边的三个数组\(u,v,w\)之外还需要两个数组\(first,next\),其中\(first\)用来保存与第i号顶点相连的第1条边是第k号边(\(first[i]=k\)),\(next\)数组用来保存连在同一个顶点上的边的先后关系,\(first,next\)均初始化为-1。
例:
4 5//点数和边数
1 4 9//边的描述,链接u顶点和v顶点,权值为w
4 3 8
1 2 5
2 4 6
1 3 7
序号 | \(u\) | \(v\) | \(w\) | \(first\) | \(next\) |
---|---|---|---|---|---|
1 | 1 | 4 | 9 | 5 | -1 |
2 | 4 | 3 | 8 | 4 | -1 |
3 | 1 | 2 | 5 | -1 | 1 |
4 | 2 | 4 | 6 | 2 | -1 |
5 | 1 | 3 | 7 | -1 | 3 |
每次加入一条边,如果这条边是以左顶点开始的第一条边,那么此时的\(next\)为-1,\(first\)为此时边的编号,如果不是第一条边,那么\(next\)为者条边的坐定点对应的上一条边的编号也就是\(first\),而\(first\)修改为此时边的编号。
代码
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=11111;
class AdjacencyList {
private:
int w[maxn],v[maxn],u[maxn],first[maxn],nxt[maxn];
int n,m;
public:
void GetGraph();
void TraverseG();
};
void AdjacencyList::GetGraph() {
memset(first,-1,sizeof(first));
memset(nxt,-1,sizeof(nxt));
cin >> n >> m;
for(int i=1; i<=m; i++) {
cin >> u[i] >> v[i] >> w[i];
nxt[i] = first[u[i]];
first[u[i]] = i;
}
return;
}
void AdjacencyList::TraverseG() {
for(int i=1; i<=n; i++) {
int k = first[i];
while(k!=-1) {
cout << u[k] << " " << v[k] << " " << w[k] <<endl;
k = nxt[k];
}
}
return;
}
int main(int argc, char const *argv[])
{
freopen("in.in","r",stdin);
AdjacencyList mygraph;
mygraph.GetGraph();
mygraph.TraverseG();
return 0;
}