001.图的存储

转载出处董晓老师

1.邻接矩阵

二维数组\(w[u][v]\)存储点\(u\)到点\(v\)的边权
时间复杂度:\(O(n^2)\)
空间复杂度:\(O(n^2)\)
应用:稠密图以外基本不用

(1)加边操作

void add(int a, int b, int c)
{
	w[a][b] = c;
}

(2)遍历操作

void dfs(int u)
{
    ···
	vis[u] = true;
	for (int v = 1; v <= n; v++)
	{
		if (w[u][v])
		{
			...
			if (vis[v]) continue;
			dfs(v);
			...
		}
	}
	...
}

2.边集数组

边集数组\(e[i]\)存第\(i\)条边的\(\{起点u,终点v,边权w\}\)
时间复杂度:\(O(nm)\)
空间复杂度:\(O(m)\)
应用:Kruskal算法

(1)加边操作

struct edge
{
	int u, v, w;
}e[M];

void add(int i, int a, int b, int c)
{
	e[i] = { a,b,c };
}

(2)遍历操作

void dfs(int u)
{
	...
	vis[u] = true;
	for (int i = 1; i <= m; i++)
	{
		if (e[i].u == u)
		{
			int v = e[i].v, w = e[i].w;
			...
			if (vis[v]) continue;
			dfs(v);
			...
		}
	}
	...
}

3.邻接表

出边数组\(e[u][i]\)存储u点的所有出边的\(\{终点v,边权w\}\)
时间复杂度:\(O(n+m)\)
空间复杂度:\(O(n+m)\)
应用:各种图,不能存反向边

(1)加边操作

struct edge
{
	int v, w;
};
vector<edge> e[N];

void add(int a, int b, int c)
{
	e[a].push_back({ b,c });
}

(2)遍历操作

void dfs(int u, int fa)
{
	...
	for (auto ed : e[u])
	{
		int v = ed.v, w = ed.w;
		if (v == fa) continue;
		...
		dfs(v, u);
		...
	}
	...
}

4.链式前向星

一个表头数组悬挂多个链表
边集数组\(e[i]\)存储第\(i\)条边的\(\{终点v,边权w,下一条边ne\}\)
表头数组\(h[u]\)存储\(u\)点的第一条出边的编号
边的编号\(idx=0,1,2,···\)
时间复杂度:\(O(n+m)\)
空间复杂度:\(O(n+m)\)

(1)加边操作

struct edge
{
	int v, w, ne;
}e[M];
int idx, h[N];

void add(int a, int b, int c)
{
	e[idx] = { b,c,h[a] };
	h[a] = idx++;
}

(2)遍历操作

void dfs(int u, int fa)
{
	...
	for (int i = h[u]; ~i; i = e[i].ne)
	{
		int v = e[i].v, w = e[i].w;
		if (v == fa) continue;
		...
		dfs(v, u);
		...
	}
	...
}
posted @ 2025-06-16 20:04  _P_D_X  阅读(10)  评论(0)    收藏  举报