class Graph
{
public:
Graph();
Graph(unsigned int vtxCount, unsigned int edgeCount);
~Graph();
void create(unsigned int vtxCount, unsigned int edgeCount); //给图的结点容器和边容器分配内存
int addVtx(); //添加空结点
void addEdges(int i, int j, int w); //添加点之间的边n-link
void addTermWeights(int i, int sourceW, int sinkW); //添加结点到顶点的边t-link
private:
class Vtx //结点类
{
public:
Vtx *next; //在maxflow算法中用于构建先进-先出队列
int first; //首个相邻边
};
class Edge //边类
{
public:
int dst; //边指向的结点
int next; //该边的顶点的下一条边
int weight; //边的权重
};
std::vector<Vtx> vtcs; //存放所有的结点
std::vector<Edge> edges; //存放所有的边
int flow; //图的流量
};
Graph::Graph()
{
}
Graph::Graph(unsigned int vtxCount, unsigned int edgeCount)
{
create(vtxCount, edgeCount);
}
Graph::~Graph()
{
}
void Graph::create(unsigned int vtxCount, unsigned int edgeCount) //构造函数的实际内容,根据节点数和边数
{
vtcs.reserve(vtxCount);
edges.reserve(edgeCount + 2);
}
/*
函数功能:添加一个空结点,所有成员初始化为空
参数说明:无
返回值:当前结点在集合中的编号
*/
int Graph::addVtx()
{
Vtx v;
memset(&v, 0, sizeof(Vtx)); //将结点申请到的内存空间全部清0(第二个参数0) 目的:由于结点中存在成员变量为指针,指针设置为null保证安全
vtcs.push_back(v);
return (int)vtcs.size() - 1; //返回值:当前结点在集合中的编号
}
/*
函数功能:添加一条结点i和结点j之间的边n-link(普通结点之间的边)
参数说明:
int---i: 弧头结点编号
int---j: 弧尾结点编号
int---w: 正向弧权值
返回值:无
*/
void Graph::addEdges(int i, int j, int w)
{
assert(i >= 0 && i < (int)vtcs.size());
assert(j >= 0 && j < (int)vtcs.size());
assert(w >= 0);
assert(i != j);
Edge fromI; // 正向弧:fromI, 反向弧 toI
fromI.dst = j; // 正向弧指向结点j
fromI.next = vtcs[i].first; //每个结点所发出的全部n-link弧(4个方向)都会被连接为一个链表,采用头插法插入所有的弧
fromI.weight = w; // 正向弧的权值w
vtcs[i].first = (int)edges.size(); //修改结点i的第一个弧为当前正向弧
edges.push_back(fromI); //正向弧加入弧集合
}
int main()
{
Graph g(5, 25);
for (int i = 0; i < 5; i++)g.addVtx();
g.addEdges(0, 2, 3);
return 0;
}
图的邻接表结构
最新推荐文章于 2024-08-25 10:23:41 发布