关于图论的问题,不管涉及什么算法,首先我们都要面对一个问题就是如何存图。那么我们会有两个选择,先介绍邻接矩阵存图的方式
一.邻接矩阵
邻接矩阵去存图,就是开一个A[n][n]的数组代表从i到j的边的权值大小如A【i】【j】=2;意义是从i到j的边权值为2;
这里给出一个有向有权图的例子

#inlucde<bits/stdc++.h>
using namespace std;
int w[100000][100000];
int main()
{int n,a,b,c;
cin>>n;
for(int i=i;i<=n;i++)
{
cin>>a>>b>>c;
w[a][b]=c;
}

若是无向图只需多加一句w[b][a]=c即可
这种方法好处是容易理解,并且在找某个节点的所有出边是只需遍历即可,但是坏处也很明显,就是它是一种稀疏存图方法,会有大量空间被浪费,为了解决这个问题下面主要介绍邻接表
二. 邻接表*
这种存图方法的优势就在于,不会有任何空间被浪费,我们可以只通过存边的方式来存储所有的边,在这里我们不引入复杂的链表去进行存储,只需采用数组和一些结构体去模拟即可,首先我们建立一个结构体,其中包含u,v,t,next分别代表这条边的起点终点和权值以及这条边之后的下一条出边,刚开始,我们可能难以理解next的用处实际上,就是next帮助我们模拟了链表的功能,首先我们还需要一个head【i】数组存储第一条i节点的出边,事实上,head数组也是该边最后一次出现,具体体现到代码实现上应该是这样

#include<bits/stdc++.h>
using namespace std;
struct edge{
	int u,v,t,next;
}e[maxm];
int head[10000];
int main()
{
int n,a,b,c;
cin>>n;
for(int i=1;i<=n;i++)
{cin>>a>>b>>c;
e[i].u=a;
e[i].v=b;
e[i].t=c;
e[i].next=head[a];
head[a]=i;
}
return 0;
}

其实到这里,可能还是不太能理解他的意义,因为head数组永远只能存储一个值,就是这条边最后一次出现的位置,那么next【i】所记录的就是这个点上一次所出边的位置,也就是说我们如果要遍历第i个点只需从head出发,持续进行next查询,遍历某个点的操作也可以自己模拟
代码很简单
如果要遍历1号节点

k=head[1];// 1号顶点其中的一条边的编号(其实也是最后读入的边)
    while(k!=0) //其余的边都可以在next数组中依次找到
    {
        printf("%d %d %d\n",u[k],v[k],w[k]);
        k=next[k];
    }

也就是说,只有在处理节点相同时next和head才会有所关联并且不会重复,我们可以模拟一个简单的图来帮助理解这个功能随便偷了一个图来举例

4 5
    1 4 9
    4 3 8
    1 2 5
    2 4 6
    1 3 7

这些就是这个图其实也就是

python 邻接矩阵转换为稠密矩阵 邻接矩阵怎么转换成图_ci


python 邻接矩阵转换为稠密矩阵 邻接矩阵怎么转换成图_ci_02


就按照程序顺序模拟初始head都为0每次都会更新,并且在更新前会用next存储他的上次出现

python 邻接矩阵转换为稠密矩阵 邻接矩阵怎么转换成图_权值_03


python 邻接矩阵转换为稠密矩阵 邻接矩阵怎么转换成图_python 邻接矩阵转换为稠密矩阵_04


python 邻接矩阵转换为稠密矩阵 邻接矩阵怎么转换成图_python 邻接矩阵转换为稠密矩阵_05


按照这个顺序存完后值就为这样在next为0钱不停止遍历就可以找到该节点所有的出边