前向星是图的一种存储结构,保存图的边集。如果给出的是边的信息,那么使用前向星的时刻便到了。
本文参考文章 前向星与链式前向星
首先构建边的结构
struct NODE
{
int from; //起点
int to; //终点
bool operator < (const NODE & a) const
{
return (from == a.from&&to<a.to) || from<a.from;
}
};
这里的比较符重载十分关键,保证了边集可以按起点排序,同一起点便按终点排序。
NODE edge[maxm]
便是边集了,但是仅仅有边集是不够的,比如有一个节点,如果想找其指向的下一个节点,不得不在边集里遍历查找该节点为起点的边,效率很低。此时需要head[]
数组来记录节点所对应的边,head[0]表示点0为起点所对应的第一条边在edge数组中的下标,以此类推。head[]
数组初始化如下
void Init()
{
for (int i = 0; i<m; ++i) //读入数据
cin >> edge[i].from >> edge[i].to;
sort(edge, edge + m); //排序
memset(head, -1, sizeof(head));
head[edge[0].from] = 0;
for (int i = 1; i<m; ++i)
if (edge[i].from != edge[i - 1].from) head[edge[i].from] = i;
}
图的遍历便简单多了,假设图中节点数n,边数m,遍历过程如下
void solve() //遍历整个图
{
for (int i = 0; i < n; ++i)
{
for (int k = head[i]; edge[k].from == i&&k<m; ++k)
{
cout << edge[k].from << " " << edge[k].to << endl;
}
}
}
完整代码如下,转自 前向星与链式前向星
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100;
const int maxm = 1000;
int head[maxn]; //存储起点为i的第一条边的位置
int n, m; //n为节点数,m为边数
struct NODE
{
int from; //起点
int to; //终点
bool operator < (const NODE & a) const
{
return (from == a.from&&to<a.to) || from<a.from;
}
};
NODE edge[maxm];
void Init()
{
for (int i = 0; i<m; ++i) //读入数据
cin >> edge[i].from >> edge[i].to;
sort(edge, edge + m); //排序
memset(head, -1, sizeof(head));
head[edge[0].from] = 0;
for (int i = 1; i<m; ++i)
if (edge[i].from != edge[i - 1].from) head[edge[i].from] = i;
}
void solve() //遍历整个图
{
for (int i = 0; i < n; ++i)
{
for (int k = head[i]; edge[k].from == i&&k<m; ++k)
{
cout << edge[k].from << " " << edge[k].to << endl;
}
}
}
int main()
{
cin >> n >> m;
Init();
solve();
}