图论常用的构图方法


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

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





阅读更多
上一篇最优性原理及其证明
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭