首页 > 代码库 > 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 图论入门