图的存储

图的存储方式

在说最短路之前,先介绍一下图的几个存储方式:主要有vector、邻接表和链式前向星三种存储方式。其中会牵扯到稀疏图和稠密图的概念,稠密图指点的个数的平方和边的个数是一个数量级的(\(n^2 ≈ m\))两者数量级类似别称为稀疏图

<1:vector存图

vector适合存稀疏图,直接看代码:

vector<int> G[maxn];
for(int i=1;i<=m;++i){
	cin>>from>>to;
    G[from].push_back(to);
    G[to].push_back(from);	//无向图一条边会被存两次
}

<2:领接表存图(有错,有时间给改一改)

领接表适合存稠密图,可以用数组模拟出来,看代码:

int head[maxn];	//头结点数组
int ne[maxn];	//邻接点数组
for(int i=1;i<=n;++i)
    head[i]=-1;			//初始化
for(int i=1;i<=m;++i)
{
    int a,b,val;
    cin>>a>>b>>val;
    ne[a]=head[a];
    head[a]=i;
}

❤️:链式星向前

链式星向前其实就是邻接表的改进版本。

const int maxn=1e5+10;
struct node
{
    int nex,to,val;
}Edge[maxm];        //nex表示与当前边起点一样的另一条边在弄的数组中的位置,to表示边的终点
int head[maxn];     //head[i]表示从i出发的点的链表的第一个点在node数组中的位置。
int tot=0;          //当前已有边的个数。
void Add(int from,int to,int val)
{
    Edge[++tot].to=to;
    Edge[tot].val=val;
    Edge[tot].nex=head[from]; //当前结点指向以前的头结点
    head[from]=tot;           //当前结点变为头结点
}
void Use(int i)               //遍历起点为i的链表
{
    int t=head[i];
    while(t!=-1)
    {
        cout<<"from "<<i<<"to "<<Edge[t].to<<"is "<<Edge[t].val<<endl;
        t=Edge[t].to;
    }
}
int main()
{
    int from,to,n;
    memset(head,-1,sizeof(head));
    memset(Edge,-1,sizeof(node));
    while(cin>>from>>to>>n,from&&to&&n)
        Add(from,to,n);
    int i;
    cin>>i;
    Use(i);
}
posted @ 2020-02-02 14:48  StungYep  阅读(225)  评论(0编辑  收藏  举报