graph
图结构模板
图主要有点集`nodes`和边集`edges`构成,这里选用unordered结构的原因是因为hashmap比普通的map查询更快。`Node`是基本点的wrapper,这么做是为了方便算法编写。
``` c++ "node的基本结构"
struct Node{
int value;//基本点的序号,即点1、点2...
int in;//该点的入度
int out;//该店的出度
unordered_set<Node*,HashNodeptr,EqualNodeptr> nexts;//该set表示由该点出发可以到达的第一个邻居节点
unordered_set<Edge*,HashEdgePtr,EqualEdgePtr> edges;//该set表示属于该点的边,即从该点出发的边
Node (int v):value(v){
in=0;
out=0;
}
}因为结构体相互嵌套的原因,所以必须使用指针。
使用上面的图结构,只需要写一个转换接口就可以使用。假设采用这样一种图接口:一个二维数组:每一行表示一个节点:`[Node from,Node to,int weight]`,下面是一个栗子。
``` c++ "转化函数"
Graph* Transform(vector<vecotr<int>>& nums){
Graph* graph=new Graph;
for(auto elem:nums){
int from=elem[0];
int to=elem[1];
int weight=elem[2];
//没有构造过该节点,将该节点加入nodes
//比如[1,2,0]和[2,3,0],在处理第一个边时节点2已经构造好了,只需要更新节点相关信息即可
if(graph->nodes.find(from)==graph->nodes.end()){
graph->nodes.insert(pair<int,Node>(from,*new Node(from)));
}
if(graph->nodes.find(to)==graph->nodes.end()){
graph->nodes.insert(pair<int,Node>(to,*new Node(to)));
}
//这里不能使用at,因为返回值copy,除非对应的value是指针,无所谓copy与否,使用find返回迭代器直接修改
auto from_iter=graph->nodes.find(from);
auto to_iter=graph->nodes.find(to);
//更新入度出度
from_iter->second.out++;
to_iter->second.in++;
//更新邻居节点
from_iter->second.nexts.insert(&to_iter.second);
Edge* edge=new Edge(weight,&from_iter.second,&to_iter.second);
from_iter->second.edges.insert(edge);
graph->edges.insert(*edge);
//一个节点处理完毕
}
return graph;
}图结构java模板
图遍历
BFS
拓扑排序
p算法
最短路径
Last updated