关闭

图论常用的构图方法

481人阅读 评论(0) 收藏 举报


一、最常用的邻接图(最简单的构图方法)

用一个二维数组表示节点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使用方便





0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:33843次
    • 积分:429
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:10篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论