邻接矩阵 订阅
逻辑结构分为两部分:V和E集合,其中,V是顶点,E是边。因此,用一个一维数组存放图中所有顶点数据;用一个二维数组存放顶点间关系(边或弧)的数据,这个二维数组称为邻接矩阵。邻接矩阵又分为有向图邻接矩阵和无向图邻接矩阵 展开全文
逻辑结构分为两部分:V和E集合,其中,V是顶点,E是边。因此,用一个一维数组存放图中所有顶点数据;用一个二维数组存放顶点间关系(边或弧)的数据,这个二维数组称为邻接矩阵。邻接矩阵又分为有向图邻接矩阵和无向图邻接矩阵
信息
外文名
Adjacency Matrix
分    类
有向图邻接矩阵和无向图邻接矩阵
科    目
数据结构
中文名
邻接矩阵
简    介
表示顶点之间相邻关系的矩阵
邻接矩阵定义
邻接矩阵(Adjacency Matrix)是表示顶点之间相邻关系的矩阵。设G=(V,E)是一个图,其中V={v1,v2,…,vn} [1]  。G的邻接矩阵是一个具有下列性质的n阶方阵:①对无向图而言,邻接矩阵一定是对称的,而且主对角线一定为零(在此仅讨论无向简单图),副对角线不一定为0,有向图则不一定如此。②在无向图中,任一顶点i的度为第i列(或第i行)所有非零元素的个数,在有向图中顶点i的出度为第i行所有非零元素的个数,而入度为第i列所有非零元素的个数。③用邻接矩阵法表示图共需要n^2个空间,由于无向图的邻接矩阵一定具有对称关系,所以扣除对角线为零外,仅需要存储上三角形或下三角形的数据即可,因此仅需要n(n-1)/2个空间。
收起全文
精华内容
下载资源
问答
  • 邻接矩阵

    千次阅读 2020-09-08 19:26:45
    数组(邻接矩阵)表示法无向图的邻接矩阵表示法有向图的邻接矩阵表示法有权图(网)的邻接矩阵表示法邻接矩阵的存储表示2.采用邻接矩阵表示法创建无向网 邻接矩阵 1 1 1 1      1. 数组(邻接...

    邻接矩阵

    1
    1
    1
    1
        

    1. 数组(邻接矩阵)表示法

    • 建立一个顶点表(记录各个顶点信息)和一个邻接矩阵(表示各个顶点之间关系)
      • 设图A=(V,E)有n个顶点,则
        在这里插入图片描述
      • 图的邻接矩阵是一个二位数组A.arcs[n][n],定义为:
        在这里插入图片描述

    无向图的邻接矩阵表示法

    在这里插入图片描述
    分析1:无向图的邻接矩阵是对称的;
    分析2:顶点i的=第i行(列)中1的个数;
    特别:完全图的邻接矩阵中,对角元素为0,其余1。

    有向图的邻接矩阵表示法

    在这里插入图片描述
    注:在有向图的邻接矩阵中,
    第i行含义:以结点vi为尾的弧(即出度边);
    第i列含义:以结点vi为头的弧(即入度边)。
    分析1:有向图的邻接矩阵可能是不对称的;
    分析2:顶点的出度 = 第 i 行元素之和
                 顶点的入度 = 第 i 列元素之和
                 顶点的度 = 第 i 行元素之和 + 第 i 列元素之和

    有权图(网)的邻接矩阵表示法

    在这里插入图片描述
    在这里插入图片描述

    邻接矩阵的存储表示

    两个数组分别存储顶点表邻接矩阵

    #define Maxlnt 32767     //表示极大值,即 ∞ 
    #define MVNum 100        //最大顶点数 
    typedef char VerTexType; //设顶点的数据类型为字符型 
    typedef int ArcType;     //假设边的权值类型为整型 
    
    typedef struct{
    	VerTexType vexs[MVNum];      //顶点表 
    	ArcType arcs[MVNum][MVNum];  //邻接矩阵
    	int vexnum,arcnum;           //图的当前点数和边数 
    }AMGraph; //Adjacency Matrix Graph 
    

    2.采用邻接矩阵表示法创建无向网

    在这里插入图片描述
    【算法思想】
    (1)输入总顶点数和总边数
    (2)依次输入点的信息存入顶点表中。
    (3)初始化邻接矩阵,使每个权值初始化为极大值。
    (4)构造邻接矩阵

    在这里插入图片描述

    • 邻接矩阵——有什么好处?
      • 直观、简单、好理解
      • 方便检查任意一对顶点间是否存在边
      • 方便找任一顶点的所有“邻接点”(有边直接相连的顶点)
      • 方便计算任一顶点的“度”(从该点发出的边数为“出度”,指向该点的边数为“入度”)
        • 无向图:对应行(或列)非0元素的个数;
        • 有向图:对应行非0元素的个数是“出度”;
          对应列非0元素的个数是“入度”。
    • 邻接矩阵——有什么不好?
      • 不便于增加和删除顶点
      • 浪费空间——存稀疏图(点很多而边很少)有大量无效元素
        • 对稠密图(特别是完成图)还是很合算的
      • 浪费时间——统计稀疏图中一共有多少条边
    展开全文
  • 邻接表 邻接矩阵 稀疏邻接矩阵 http://zh.wikipedia.org/wiki/%E9%82%BB%E6%8E%A5%E8%A1%A8 posted o...

    http://zh.wikipedia.org/wiki/%E9%82%BB%E6%8E%A5%E8%A1%A8

    posted on 2011-12-10 10:36 lexus 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/lexus/archive/2011/12/10/2283085.html

    展开全文
  • 三、邻接矩阵及其应用是我们在图论部分遇到的第三个难点。1.邻接矩阵的定义邻接矩阵的初始矩阵中的每个元素是顶点 vi 邻接到顶点 vj 边的条数。切记这是vi到vj直接的边,不是通路。2.邻接矩阵的应用这个才是重点。图...

    三、邻接矩阵及其应用是我们在图论部分遇到的第三个难点。

    1.邻接矩阵的定义

    654cad0b65c31f4824ba220b77ead685.png

    邻接矩阵的初始矩阵中的每个元素是顶点 vi 邻接到顶点 vj 边的条数。切记这是vi到vj直接的边,不是通路。

    2.邻接矩阵的应用

    caf6c3dd9abd3ab37afe61c64f4d0f22.png

    这个才是重点。

    图中长度为L的通路的条数,可以由图的邻接矩阵的L次方求得。邻接矩阵的L次方,就是邻接矩阵的L-1次方乘以邻接矩阵。

    将邻接矩阵的L次方中所有的元素相加,就是长度为L的通路条数;将其所有对角线的元素相加,就是长度为L的回路条数。

    例  有向图D如图所示,求 A, A2, A3, A4,并回答诸问题:

    (1) D 中长度为1, 2, 3, 4的通路各有多少条?其中回路分别为多少条?

    (2) D 中长度小于或等于4的通路为多少条?其中有多少条回路?

    943da77be50151152dab2a88697b683d.png

    2a82faa291401741f49b6f26ca8419a9.png

    (1) D中长度为1的通路为1+2+1+1+1+1+1=8条,其中有1条是回路.

        D中长度为2的通路为1+3+2+2+1+1+1=11条,其中有3条是回路.

      D中长度为3和4的通路分别为1+4+3+3+1+1+1=14和   1+5+4+4+1+1+1=17条,回路分别为1与3条.

    (2) D中长度小于等于4的通路为50条,其中有8条是回路.

    四、可图化与可简单图化是我们在图论部分遇到的第四个难点。

       1.相关定义

           V={v1, v2, …, vn}为无向图G的顶点集,称d(v1), d(v2), …, d(vn)为G的度数列  

     V={v1, v2, …, vn}为有向图D的顶点集,

     D的度数列d(v1), d(v2), …, d(vn)

     D的出度列d+(v1), d+(v2), …, d+(vn)

     D的入度列d-(v1), d-(v2), …, d-(vn) 

    7646e13f611d090c461d99a75e1f5c40.png

    结点的度数,就是与结点相关联的边的条数。一条边提供两个度,普通边将两个度提供给不同的两个结点,自回路将两个度提供给同一个结点。

    上图中v1,v2,v3,v4,v5的度分别是44,2,1,3。

    我们将度数看成一个数字序列,则(4,4,2,1,3)称为度数列。问题是,是不是所有的数字序列可以作为结点的度数,进而画出图呢?

    不是的。只有满足条件的数字序列才可以作为图中结点的度。

    如果一个非负整数列d=(d1, d2, …, dn)可以画成图,则称其是可图化的;如果一个非负整数列d=(d1, d2, …, dn)可以画成简单图,则称其是可简单图化的。

    2.可图化

    如果一个数字序列可图化,根据握手定理,

    3bda510e72a30368081b20a2c807653d.png

    则所有结点的度数之和应该是2m,是偶数,所以,数字序列可图化的充要条件是:所有数字之和是偶数。

    3.可简单图化

    简单图是无自回路、无多重边的图。一个数字序列是否可简单图化,没有充分条件,只有必要条件:图的最大度<=n-1,n是图中结点的个数。

    易知:

    (1, 2, 3, 4, 5),(3, 3, 3, 4) 都不是可图化的,也不是可简单图化的。

    (2, 4, 6, 8, 10),(1, 3, 3, 3, 4) 是可图化的,其中,(1, 1,1, 2, 3)的最大度是3,小于等于5-1=4,又是可简单图化的。

    当图的最大度=n-1时,处于临界值,这时需要去具体分析一下,是不是可简单图化。

    比如(1,3,3,3)满足可简单图化的必要条件。假设v2、v3、v4的度数均为3,v1是度数为1的结点,连接到v2。根据简单图的定义,没有自回路,没有多重边,则v2的另外两个度必然一个连接v3,一个连接v4。此时,v3的度也要为3,是不可能的,v3只能有一条连接到v4的边。否则就会有多重边出现。故(1,3,3,3)可图化,但不可简单图化。

    五、最小生成树是我们在图论部分遇到的第五个难点。

    生成树——生成子图并且是树

    生成这两个字,表示结点一个都不能少,边可以去掉一些;

    这个概念,用五个字来说,就是“连通无回路”;

    那么,最小生成树的最小,体现在哪里呢?

    最小,指的是树的最小。图中每条边都有权,一般用一个非负整数来表示,可以认为是两点间的距离、所耗费的时间等,用英文单词weight来表示

    7693a04533c707c965b7a29d4a0d240c.png

    上图中,v1和v2两个顶点之间有两条边,一条边的权为1,另一条边的权为2。我们可以理解为v1和v2两个顶点之间,通过第一条边需要用1个小时,通过第二条边需要用2个小时。当然,自回路也可以有权,比如图中v3顶点有自回路,自回路的权为1。

    22419fae9ed0bce655922677131abf61.png             a89e50be93310bfdf250edf25ecd4943.png

    对于一个图来说,它的生成树可能会有好多个。比如我们现在看到的这样的生成树,生成树中的每条边都叫树枝,所有的树枝的权之和,称之为树的权。比如说,目前这棵生成树的权是1+7+2+3+3+5+18=39,下面的这一棵生成树,它的权是2+8+3+4+18+3+4=42。这样的话,我们有的同学已经可以自己来定义最小生成树的概念了。所谓的最小生成树,就是在一个图的所有的生成树当中,找一棵权最小的生成树。

    定义  T是G=的生成树

    (1) W(T)——T各边权之和

    (2) 最小生成树——G的所有生成树中权最小的树。

    那么现在,如何去求一棵树的最小生成树呢?目前有两种成熟的算法。一种叫Kruskal(克鲁斯卡尔)算法,也叫避圈法;另一种叫Prim(普里姆)算法。现在我们来看一下避圈法。

    避圈法求最小生成树

    首先要将图中所有非环边按照权值从小到大排列,编号依次记为e1,e2,e3,……,em,当然在这个排序当中,我们允许有边的权值相同的情况出现。

    第一步,取e1在最小生成树T当中。

    第二步,检查e2,是否与e1构成回路。如果有回路出现,则舍弃e2;如果没有回路出现,则把e2也取在树T当中。

    第三步,检查e3,看e3是否与e1 e2形成回路。如果有回路出现,则舍弃e3;如果没有回路出现,则把e3也取在树T当中。如此重复,直到得到最小生成树为止

    131210f1a687f9de98f06e1e6d4db7a5.png

    下面对图G来求最小生成树。

    首先,要剔除掉图中的自回路。

    然后将其余的边按照权值从小到大排序。2,2,3,3,5,18。

    第一步,取权为2的边在树T当中。接着检查另一条权为2的边,没有回路,加入生成树。再检查权为3的两条边,一条与权为2的边形成回路,舍弃;另一条权为3的边没有回路,加入树T。再检查权为5的两条边,有回路出现,舍弃。目前,剩下了最后一条权为18的边,权很大,要不要呢?当然要!因为如果没有这一条边,我们之前纳入进来的所有的边就不是连通的,也就不能称之为树了。这样,我们就得到了这个图的最小生成树,最小生成树的权W(T)=2+2+3+18=25.

    六、最优二叉树是我们在图论部分遇到的第六个难点。

    a833087ebd21272957baf602e5619fd6.png

    求最优树的算法—— Huffman算法

    给定实数w1, w2, …, wt,且w1<=w2<=…<=wt. 

    (1)  连接权为w1, w2的两片树叶,得一个分支点,其权为w1+w2.

    (2)  在w1+w2, w3, …, wt 中选出两个最小的权,连接它们对应的顶点(不一定是树叶),得新分支点及所带的权. 

    (3)  重复(2),直到形成 t-1个分支点,t片树叶为止. 

    8cdff1580c2eaad07bdeeff2da962093.png

    一棵2叉树产生一个二元前缀码.

    一棵正则2叉树产生惟一的前缀码(按左子树标0,右子树标1)

    图所示二叉树产生的前缀码为

                         { 00, 10, 11, 011, 0100, 0101 }

    9e08141ce4393e24872a6271bcc23ce0.png

    例  在通信中,八进制数字出现的频率如下:

         0:25%          1:20%

         2:15%          3:10%

         4:10%          5:10%

         6:5%           7:5%

    求传输它们的最佳前缀码,并求传输10的n次方(n>=2)个按上述比例出现的八进制数字需要多少个二进制数字?若用等长的(长为3)的码字传输需要多少个二进制数字?

    解  用100个八进制数字中各数字出现的个数,即以100乘各频率为权,并将各权由小到大排列,得w1=5, w2=5, w3=10, w4=10, w5=10, w6=15, w7=20, w8=25. 用此权产生的最优树如图所示. 

    9fb1fff60a73b3b93282457ac687f7d8.png

        01-----0           11-----1 

        001-----2         100-----3

        101-----4         0001-----5

        00000-----6     00001-----7

    W(T)=285,即传100个以上述频率传输的数字需要285个二进制数,那么传10的n次方(n>=2)个用二进制数字需2.85*10的n次方个, 用等长码需3*10的n次方个数字. 

          注意:最小生成树和最优二叉树都不一定唯一,当其不唯一的时候,它们的权都是一致的。

    展开全文
  • 1.两种存储结构(邻接表和邻接矩阵) //图的两种存储结构 #define INF 32767 //定义∞ #define MAXV 100 //最大顶点个数 typedef char InfoType; //以下定义邻接矩阵类型 typedef struct { int no; //...

    1.两种存储结构(邻接表和邻接矩阵)

    //图的两种存储结构
    #define INF 32767				//定义∞
    #define	MAXV 100				//最大顶点个数
    typedef char InfoType;
    
    //以下定义邻接矩阵类型
    typedef struct
    {	int no;						//顶点编号
    	InfoType info;				//顶点其他信息
    } VertexType;					//顶点类型
    typedef struct
    {	int edges[MAXV][MAXV];		//邻接矩阵数组
    	int n,e;					//顶点数,边数
    	VertexType vexs[MAXV];		//存放顶点信息
    } MatGraph;						//完整的图邻接矩阵类型
    
    //以下定义邻接表类型
    typedef struct ANode
    {	int adjvex;					//该边的邻接点编号
    	struct ANode *nextarc;		//指向下一条边的指针
    	int weight;					//该边的相关信息,如权值(用整型表示)
    } ArcNode;						//边结点类型
    typedef struct Vnode
    {	InfoType info;				//顶点其他信息
    	int count;					//存放顶点入度,仅仅用于拓扑排序
    	ArcNode *firstarc;			//指向第一条边
    } VNode;						//邻接表头结点类型
    typedef struct 
    {	VNode adjlist[MAXV];		//邻接表头结点数组
    	int n,e;					//图中顶点数n和边数e
    } AdjGraph;						//完整的图邻接表类型
    

    2.图的基本运算

    //图的基本运算算法
    #include <stdio.h>
    #include <malloc.h>
    #include "graph.h"
    //------------------------------------------------------------
    //----邻接矩阵的基本运算算法----------------------------------
    //------------------------------------------------------------
    void CreateMat(MatGraph &g,int A[MAXV][MAXV],int n,int e) //创建图的邻接矩阵
    {
    	int i,j;
    	g.n=n; g.e=e;
    	for (i=0;i<g.n;i++)
    		for (j=0;j<g.n;j++)
    			g.edges[i][j]=A[i][j];
    }
    void DispMat(MatGraph g)	//输出邻接矩阵g
    {
    	int i,j;
    	for (i=0;i<g.n;i++)
    	{
    		for (j=0;j<g.n;j++)
    			if (g.edges[i][j]!=INF)
    				printf("%4d",g.edges[i][j]);
    			else
    				printf("%4s","∞");
    		printf("\n");
    	}
    }
    //------------------------------------------------------------
    
    //------------------------------------------------------------
    //----邻接表的基本运算算法------------------------------------
    //------------------------------------------------------------
    void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e) //创建图的邻接表
    {
    	int i,j;
    	ArcNode *p;
    	G=(AdjGraph *)malloc(sizeof(AdjGraph));
    	for (i=0;i<n;i++)								//给邻接表中所有头结点的指针域置初值
    		G->adjlist[i].firstarc=NULL;
    	for (i=0;i<n;i++)								//检查邻接矩阵中每个元素
    		for (j=n-1;j>=0;j--)
    			if (A[i][j]!=0 && A[i][j]!=INF)			//存在一条边
    			{	p=(ArcNode *)malloc(sizeof(ArcNode));	//创建一个结点p
    				p->adjvex=j;
    				p->weight=A[i][j];
    				p->nextarc=G->adjlist[i].firstarc;	//采用头插法插入结点p
    				G->adjlist[i].firstarc=p;
    			}
    	G->n=n; G->e=n;
    }
    void DispAdj(AdjGraph *G)	//输出邻接表G
    {
    	int i;
    	ArcNode *p;
    	for (i=0;i<G->n;i++)
    	{
    		p=G->adjlist[i].firstarc;
    		printf("%3d: ",i);
    		while (p!=NULL)
    		{
    			printf("%3d[%d]→",p->adjvex,p->weight);
    			p=p->nextarc;
    		}
    		printf("∧\n");
    	}
    }
    void DestroyAdj(AdjGraph *&G)		//销毁图的邻接表
    {	int i;
    	ArcNode *pre,*p;
    	for (i=0;i<G->n;i++)			//扫描所有的单链表
    	{	pre=G->adjlist[i].firstarc;	//p指向第i个单链表的首结点
    		if (pre!=NULL)
    		{	p=pre->nextarc;
    			while (p!=NULL)			//释放第i个单链表的所有边结点
    			{	free(pre);
    				pre=p; p=p->nextarc;
    			}
    			free(pre);
    		}
    	}
    	free(G);						//释放头结点数组
    }
    //------------------------------------------------------------
    

    3.相互转换

    #include "graph.cpp"
    void MatToList(MatGraph g,AdjGraph *&G)		//将邻接矩阵g转换成邻接表G
    {	int i,j;
    	ArcNode *p;
    	G=(AdjGraph *)malloc(sizeof(AdjGraph));
    	for (i=0;i<g.n;i++)				//将邻接表中所有头结点的指针域置初值
    		G->adjlist[i].firstarc=NULL;
    	for (i=0;i<g.n;i++)				//检查邻接矩阵中每个元素
    		for (j=g.n-1;j>=0;j--)
    			if (g.edges[i][j]!=0 && g.edges[i][j]!=INF)	//存在一条边
    			{	p=(ArcNode *)malloc(sizeof(ArcNode));	//创建一个边结点p
    				p->adjvex=j; p->weight= g.edges[i][j];
    				p->nextarc=G->adjlist[i].firstarc;		//采用头插法插入结点p
    				G->adjlist[i].firstarc=p;
    			}
    	G->n=g.n;G->e=g.e;
    }
    void ListToMat(AdjGraph *G,MatGraph &g) //将邻接表G转换成邻接矩阵g
    {	int i;
    	ArcNode *p;
    	for (i=0;i<G->n;i++)			//扫描所有的单链表
    	{	p=G->adjlist[i].firstarc;	//p指向第i个单链表的首结点
    		while (p!=NULL)				//扫描第i个单链表
    		{	g.edges[i][p->adjvex]=p->weight;
    			p=p->nextarc;
    		}
    	}
    	g.n=G->n;g.e=G->e;
    }
    
    int main()
    {
    	MatGraph g;
    	AdjGraph *G;
    	int A[MAXV][MAXV]={{0,1,0,1,1},{1,0,1,1,0},
    			{0,1,0,1,1},{1,1,1,0,1},{1,0,1,1,0}};
    	int n=5, e=8;
    	CreateMat(g,A,n,e);			//建立《教程》中图8.1(a)的邻接矩阵
    	printf("图G的邻接矩阵:\n");
    	DispMat(g);					//输出邻接矩阵g
    	printf("将g转换为邻接表G\n");
    	MatToList(g,G);				//输出邻接表G
    	printf("图G的邻接表:\n");
    	DispAdj(G);
    	DestroyAdj(G);				//销毁邻接表
    	CreateAdj(G,A,n,e);			//建立《教程》中图8.1(a)的邻接表
    	printf("图G的邻接表:\n");
    	DispAdj(G);					//输出邻接表G
    	printf("将G转换为邻接矩阵g\n");
    	ListToMat(G,g);
    	DispMat(g);					//输出邻接矩阵g
    	DestroyAdj(G);				//销毁邻接表
    	return 1;
    }
    
    展开全文
  • 图的邻接矩阵

    2018-06-12 19:27:18
    图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵图的邻接矩阵
  • 稀疏图为什么用邻接表存储而不用邻接矩阵邻接表只需存储非零节点,而矩阵的话是不是要把所有节点的信息都保存上啊,而稀疏图的非零节点不多啊.所以存储效率高罗马尼亚问题 稀疏图还是稠密图?邻接表还是邻接矩阵?...
  • 主讲人 李 刚 图的邻接矩阵表示法 C 目 录 ONTENTS 01 邻接矩阵的定义 邻接矩阵的定义 1 邻接矩阵是表示顶点之间相邻关系的矩阵设图G是具有n个顶点的图无论是有向图还是无向图则G的邻接矩阵是具有如下性质的n阶方阵 ...
  • 前面分别介绍了邻接矩阵无向图的C和C++实现,本文通过Java实现邻接矩阵无向图。目录1. 邻接矩阵无向图的介绍2. 邻接矩阵无向图的代码说明3. 邻接矩阵无向图的完整源码转载请注明出处:...
  • 邻接矩阵邻接矩阵概念无向图和有向图在邻接矩阵中的表示方法:有向图和无向图的表示方法无向图和有向图大同小异,在这里只以无向图为例,代码部分通过简单调整即可对应编译有向图邻接矩阵数据类型定义#define ...
  • (1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接矩阵ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中...
  • (1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接矩阵ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中...
  • (1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接矩阵ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,659
精华内容 7,063
关键字:

邻接矩阵