方法:使用一个支持动态增加元素的数据结构构成的数组,如 vector< int> adj[n + 1] 来存边,其中 adj[u] 存储的是点u的所有出边的相关信息(终点、边权等);
复杂度:
struct Edge{
int u,v;//边的端点
int w;//权重
}Edges[MAXN];
方法:本质是用数组模拟链表,主要有两个数组
Edges[MAXN] 存储边的信息,包括两个端点、权重、下一条边在Edges中的索引;
head[MAXN] head[i]为节点i的第一条出边在Edges中的序号;
在插入边的时候维护一个tot变量记录总计的边的个数
复杂度:
代码板子:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6;
struct Edge
{//边结构体
int u,v;//边的端点;
int w;//权重
int nxt;//下一条边在Edge中的索引
}Edges[MAXN];
int head[MAXN];//每个节点出边
int tot;//总的边数,随着边的增加而增加
void init(int n){
tot=0;
//初始化head数组
for(int i=0; i<n; i++)
head[i]=-1;
//memset(head,-1,sizeof(head));
//memset是以字节为单位,初始化内存块
//字节单位的数组时,可以用memset把每个数组单元初始化成任何你想要的值
//因为一个int类型的变量占4个字节,而memset是将每一个字节初始化成1,
//所以一个int类型的变量被初始化成了0x01010101。而这个数是16843009
//memset初始化int只能初始化0和-1;
}
void addEdge(int u,int v,int w){
Edges[tot].u=u;
Edges[tot].v=v;
Edges[tot].w=w;
Edges[tot].nxt=head[u];
head[u] = tot;
tot++;
}
void dfs(int u) {
//v 可以是图中的一个顶点
//也可以是抽象的概念,如 dp 状态等,这一点很难想
vis[u] = 1; //标记该节点被访问过
for (int i = head[u]; i; i = Edges[i].nxt) {
if (!vis[Edges[i].v]) {
//task to do
dfs(v);
}
}
}
void bfs(int u){
vector<int> d;//记录到达各个节点的最近距离;
vector<int> p;//记录最短路上的节点
vector<int> vis(MAXN,0);//0代表节点未被访问过
queue<int> q;
q.push(u);
vis[u]=1;//标记访问
d[u]=0;
p[u]=-1;
while(!q.empty()){
u=q.front();
q.pop();
for(int i=head[u]; i; i=Edges[i].nxt){
int v = Edges[i].v;//到达的点
if(!vis[v]){
q.push(v);
vis[v]=1;
d[v]=d[u]+1;
p[v]=u;//记录前序节点
//task to do
}
}
}
}
??
??
原文:https://www.cnblogs.com/Smartog/p/14978554.html