一、最常用的邻接图(最简单的构图方法)
用一个二维数组表示节点i到j的路径长度,可以初始化为-1,来表示不存在i到j的路径
这种方法的缺点在于占用空间较大,在用边频繁的时候不方便,代码如下
#define Max_Node_Num 1000
int graph[Max_Node_Num][Max_Node_Num];
int node_num,edge_num;
void build_graph()
{
//初始化,使用-1来表示不存在边
memset(graph,0xff,sizeof(graph));
//输入节点数及边数
scanf("%d%d",&node_num,&edge_num);
//输入边,构造图
int from,to,value;
for (int i = 0;i < edge_num;i++){
scanf("%d%d%d",&from,&to,&value);
graph[from][to] = value;
}
}
二、用指针实现的邻接表
#define Max_Node_Num 1000
struct Edge
{
int des;
int value;
Edge * next;
Edge(){
des = value = 0;
next = NULL;
}
Edge(int a,int b,Edge * n){
des = a;
value = b;
next = n;
}
};
//每个节点保存一个链表,记录从这个节点出去的边
Edge * nodes[Max_Node_Num];
int node_num,edge_num;
void build_graph(){
//输入节点数,边数
scanf("%d%d",&node_num,&edge_num);
//初始化
for (int i = 0;i < node_num;i++)
nodes[i] = NULL;
int from,to,value;
for (int i = 0;i < edge_num;i++){
scanf("%d%d%d",&from,&to,&value);
//把from节点的队列放入next
Edge *e = new Edge(to,value,nodes[from]);
//将节点变成链表头
nodes[from] = e;
}
}
三、用vector实现的邻接表
#define Max_Node_Num 1000
struct Edge{
int des;
int value;
Edge(){
des = value = 0;
}
Edge(int a,int b){
des = a;
value = b;
}
};
vector<Edge> nodes[Max_Node_Num];
int node_num,edge_num;
//有向图构图
void build_graph(){
//输入节点数,边数
scanf("%d%d",&node_num,&edge_num);
//初始化
for (int i = 0;i < node_num;i++)
nodes[i].clear();
int from,to,value;
//输入每条边信息
for (int i = 0;i < edge_num;i++){
scanf("%d%d",&from,&to,&value);
nodes[from].push_back(Edge(to,value));
}
}
四、用数组实现的邻接表
#include <iostream>
using namespace std;
#define Max_Node_Num 1000
#define Max_Edge_Num 1000000
struct Edge{
int des;
int value;
int next;
};
//记录每条边的信息
Edge edges[Max_Edge_Num];
//用数组记录节点最后加入的边的编号
int nodes[Max_Node_Num];
int node_num,edge_num;
void build_graph(){
scanf("%d%d",&node_num,&edge_num);
//初始化节点,初始化为-1,即表示没有从此节点出的边
memset(nodes,0xff,sizeof(nodes));
int from,to,value;
for (int i = 0;i < edge_num;i++){
scanf("%d%d%d",&from,&to,&value);
edges[i].des = to;
edges[i].value = value;
//将此边的下一条边记录为from节点此前最后加入的边
edges[i].next = nodes[from];
//在nodes数组中记录从from节点出的最后一条边的编号
nodes[from] = i;
}
}
此种方法遍历一个节点出去的所有边的方法如下:
for(i=p[u];i!=-1;i=edg[i].next)
完!
最后一种方法在遍历所有边上有优势,vector使用方便