ACM入门教程-图的存储

简单来说图就是由一些点与一些边组成,点与点可以通过边连接每条边可以由权值,那么通过题目的输入如何来储存一张图呢?

图的存储

结构体

要解决这个问题,我们首先需要知道需要储存图的那些信息,对于一组数据会给出起点、终点、边长。
那么最简单的方法就是用一个结构体数组来存储所有的信息。

struct edge{
int a,b,w;//起点为a,终点为b,边权为w
}e[maxn];
int main()
{
   for(int i=1;i<=edge_num;i++)
   {  
     int a,b,w;
     cin>>a>>b>>w;
     e[i].a=a,e[i].b=b,e[i].c=w;
     //e[i]={a,b,w};
   }
}

这样做显然是可以存储下我们想要的信息的,但是如果我们想要知道两个点之间是否之间相连,那我们只能通过遍历所有边的方式来获取这个信息。时间复杂度是O(n)

//a 与b是否之间是否有边?
int have_edge(int a,int b){
	for(int i=1;i<=edge_num;i++)
	{
	  if(e[i].a==a&&e[i].b==b)
	  return e[i].w;
	}
}

邻接矩阵

为了快速可以判断两个点之间是否有边,我们可以用邻接矩阵的方式来存储图。

int gra[N][N];//N为点的个数
void get_edge()
{  
   memset(gra,0x3f,sizeof(gra));//初始化所有点不可达
   for(int i=1;i<=edge_num;i++)
   {  
      int a,b,w;
      cin>>a>>b>>w;
      gra[a][b]=w;
   }
}

这样我们判断a、b是否有边就可以在O(1)的时间内快速判断了。邻接矩阵的劣势也很明显,那就是空间复杂度需要O(n2)如果在稀疏图中就会浪费大量的空间,并且在点数超过10000时就会超内存无法开二维数组。

邻接表

请看下面一张图,邻接表就是只存储一个点之间相连的另外一个点以及其边长,这里的结构类似于链表,也就是每个顶点都作为链表的头节点,理解好了这一点我们就有很多方式来实现这样一个过程了。
在这里插入图片描述

int h[N],e[N],ne[N],idx,w[N];//h[i]代表的是第i个节点的邻接表,idx可以理解为链表中的地址 e[idx]存放的是a节点可达的节点b,ne则是下一个节点的idx。
void add(int a,int b,int c)
{
  e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;//头插法加边
}
void get_pointEdge(int a)//获取节点a所有相连的边的权值和
{  
int sum=0;
  for(int i=h[a];i!=-1;i=ne[i])
  {  
     int ver=e[i];
      sum+=w[i];
  }
}
void innit()
{
   memest(h,-1,sizeof(h));//-1作为NUll;
}

链式前向星

与邻接表差不多,由于我写的比较少,大家可以选择着学习。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值