邻接矩阵:是直接利用一个二维数组对边的关系进行存储,矩阵的第i行第j列的值 表示 i -> j 这条边的权值;特殊的,如果不存在这条边,用一个特殊标记来表示;如果i == j,则权值为0。它的优点是实现非常简单,而且很容易理解;缺点也很明显,如果这个图是一个非常稀疏的图,图中边很少,但是点很多,就会造成非常大的内存浪费,点数过大的时候根本就无法存储。
邻接表:是图中常用的存储结构之一,每个顶点都有一个链表,这个链表的数据表示和当前顶点直接相邻的顶点(如果边有权值,还需要保存边权信息)。邻接表的优点是对于稀疏图不会有数据浪费,缺点就是实现相对麻烦,需要自己实现链表,动态分配内存.(当然也可以使用vector来实现邻接表的存储,不过时间效率会下降)
前向星:是以存储边的方式来存储图,先将边读入并存储在连续的数组中,然后按照边的起点进行排序,这样数组中起点相等的边就能够在数组中进行连续访问了。它的优点是实现简单,容易理解,缺点是需要在所有边都读入完毕的情况下对所有边进行一次排序,带来了时间开销,实用性也较差,只适合离线算法。
链式前向星:链式前向星和邻接表类似,也是链式结构和线性结构的结合,每个结点i都有一个链表,链表的所有数据是从i出发的所有边的集合(对比邻接表存的是顶点集合)。这种结构在无论是稠密的还是稀疏的图上都有非常好的表现,空间上没有浪费,时间上也是最小开销。具体实现看下面的代码
/*
采用链式前向星存储边
*/
#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=30005;
struct Edge
{
int to,cost;// edge[i].to表示编号为i的边所连接下个点 ,edge[i].cost表示编号为i的边 的权值
int next;//edge[i].next表示与编号为i的边同起点的上一条边的编号
}edge[MAXN];//存放边
int tol;
int head[MAXN];//head[i]存储当前以i点为起点的边的编号
void addedge(int u,int v,int w)//添加边
{
edge[tol].to=v;
edge[tol].cost=w;
edge[tol].next=head[u];
head[u]=tol++;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)//点数n,边数m
{
tol=0;
memset(head,-1,sizeof(head));
int a,b,c;
while(m--)
{
scanf("%d%d%d",&a,&b,&c);//a到b花费c
addedge(a,b,c);
}
for(int i=1;i<=n;i++)//输出与节点i相连的边
{
for(int j=head[i];j!=-1;j=edge[j].next)
{
printf("%d->%d cost:%d\n",i,edge[j].to,edge[j].cost);
}
}
}
return 0;
}
vector来实现邻接表的存储
/*
采用vector存储边
*/
#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=30005;
struct Edge
{
int to,cost;
};
vector<Edge> G[MAXN];//G[i]代表从i出发的边,vector里存的是边
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)//点数n,边数m
{
Edge e;
int from;
while(m--)
{
scanf("%d%d%d",&from,&e.to,&e.cost);//a到b花费c
G[from].push_back(e);
}
for(int i=1;i<=n;i++)//输出与节点i相连的边
{
for(int j=0;j<G[i].size();j++)
{
Edge e=G[i][j];
printf("%d->%d cost:%d\n",i,e.to,e.cost);
}
}
}
return 0;
}