一、图的基础知识:
1.图分类:
有向图:边用带箭头的直线表示,边均为单向的
无向图:边用不带箭头的直线表示,所有的边均为双向的
带权图:边或者点加上表示某种含义的数值,称“点权”或者“边权”
2.顶点的度:
无向图:指与顶点v相连的边的数目
有向图:有出度和入度,出度是以顶点v为起点,,入度是以顶点v为终点。有向图的度=出度+入度。
所有顶点的度=边数的2倍
3.图的连通性:
联通:如果存在一条从顶点U到顶点V的路径,称U和V联通。
联通图:图中的任意两点都联通,否则的话为非连通图。
联通分量:无向图中的极大联通子图。
二、图的存储(2种方式)
1.邻接矩阵:
令图的顶点标号为0,1,.....n-1,开一个二维数组G[n][n],数组的两维分别表示图的顶点的标号。若G[i][j]为1,则顶点 i 和顶点 j 之间有边,若为0则不存在边。当然G[i][j]也可以用来存放顶点 i 到顶点 j 的边权。
但邻接矩阵有个致命的缺点就是只能存储顶点数目不大的图(一般在1000以内),否则的话会内存超限,这就需要用图的第二种存储方法来弥补这个缺点了。
2、邻接表:
依然给图的顶点依次编号为0,1,.....n-1,每个顶点都可能有若干条出边,把同一个顶点的所有出边放在一个列表中就会对应有n个列表,称为邻接表。下面用一种比较易于理解的方法来实现邻接表,利用vector来实现。
vector<int> adj[n];//存放每条边的终点编号
但是如果碰见了带有权值的图怎么办呢??????
答案依然是用vector,但是是结合结构体实现的vector,如下:
struct Node{
int v;//边的终点编号
int w;//边权
}Adj[n];
//插入顶点信息时可以声明一个Node类型的临时变量temp
//例如向顶点1中添加信息,终点为3,边权为4;
Node temp;
temp.v=3;
temp.w=4;
Adj[1].push_back(temp);
//还可以再改进一下上面的添加顶点信息的方法,用构造函数,如下:
struct Node{
int v,w;
Node(int _v,int _w):v(_v),w(_w) {}
}Adj[n];
Adj[1].push_back(Node(3,4));
图的基础知识和图的存储到此为止,下一篇文章接着讲解图的遍历。有错误请及时指出。