首页 > 代码库 > ACM 图论入门
ACM 图论入门
①图论基础
图由点和边组成
记顶点集合为V 边集合为E的图为G=(V,E)
图可分为有向图和无向图。如表示朋友关系的图为无向图,表示点之间大小关系的图为有向图。
边也可以带有权值,带有权值称为有权图,不带有权值称为 无权图。
一.关于无向图
任意两点之间都有路径的图叫做连通图,顶点连接的边数称为这个点的度。
没有环的连通图就是树,没有环的非连通图就是森林。
一棵树的边数=顶点数-1。反之 边数=顶点数-1的连通图就是树。
二.关于有向图
以一个点为起点的边数称作这个点的出度,以一个点为终点的边数称作这个点的入度。
有向无环图叫做DAG(Directed Acyclic Graph).
DAG中有一种有趣的点的编号方式:如果把点编号 使边只从编号小的点指向编号大的点 那么这种编号称为拓扑序。求解拓扑序的算法叫做拓扑排序。
有了拓扑排序,很多DAG的问题就可以用DP来解决啦。
②图的表示
研究图的问题首先要把图用具体的数据结构储存起来。
假设顶点编号为1-V 那么一般有两种图的表示方法:邻接矩阵和邻接表
一.关于邻接矩阵
邻接矩阵就是用一个V*V的二阶矩阵来保存边 [i][j]即表示i对j的关系.
在无权图中可以用 矩阵[i][j]=1 来表示i对j有一条边(在无向图中同样有矩阵[j][i]=1) 用矩阵[i][j] = 0 来表示i对j没有边。
在有权图中矩阵[i][j] = i对j的边的权值 。 如果i对j没有边 不能用=0来表示(这样就分不清权值为0的边了) 而要用INF来表示。
使用邻接矩阵的好处是可以在O(1)的时间内判断两点间的关系 但需要花费O(V^2)的空间来储存它。V很大时,这种方法不再适用。
在图中有重边或者自环的情况下,要具体分析取舍。
二.邻接表
邻接表是通过真正的储存点和边来实现的,所以其空间只需要O(E+V),但相应的时间复杂度要高。可以使用vector不定长数组来实现图的储存(push_back意为在vector尾部加入一个数据) 每个点都有一个vector数组,里面存着它连向的边。
vector<int> G[MAX_V]; /* * 若边上有属性 * 则 struct edge(int to,cost;); * vector<edge> G[MAX_V]; */ //假如有一条从s连向t的边 G[s] = push_back(t);//如果是无向图 反过来还有 G[t] = push_back(s); //下面是查询s是否有一条连向t的边 int len = G[s].size(); for(int i = 0 ; i < len ; i ++) { if(G[s][i] == t) { printf("Yes\n"); break; } if(i == len-1) printf("No\n"); }
ACM 图论入门