参考资料:
本文不做商用,只是为了更好的复习,如果有侵权请指出,十分抱歉。
定义&术语
表示
- 邻接矩阵:适合顶点数规模小、边稠密的简单图
无权图:不存在边(u,v) → a[u][v] = 0; 存在边(u,v) → a[u][v] = 1。
有权图:不存在边(u,v) → a[u][v] = ∞或-∞;存在边(u,v) → a[u][v] = 权值。
无向图中邻接矩阵按矩阵副对角线对称。
#include <bits/stdc++.h>
using namespace std;
const int MN = 1005;
int n, m, i, u, v, a[MN][MN];
int main()
{
scanf("%d%d", &n, &m);
for(i = 1; i <= m; i ++)
{
scanf("%d%d", &u, &v);
a[u][v] = 1;//有向图
//or a[u][v] = a[v][u] = 1 无向图
}
return 0;
}
- 邻接链表:适合边数相对顶点数规模较小、边稀疏图
图的邻接表是图的所有节点的邻接表的集合;而对每个节点,它的邻接表就是它的所有出弧的集合,含有终点,权值等信息。
对于有向图G=(V,E),一般用e(v)表示节点v的邻接表,即节点v的所有出弧构成的集合或链表(实际上只需要列出弧的另一个端点,即弧的尾)。
一般图都适用。邻接表方法增加或删除一条弧所需的计算工作量很少。
#include <bits/stdc++.h>
using namespace std;
const int MN = 1005;
struct info{
int to, next, val;
}e[MN * 4];
int n, m, i, j, u, v, z, head[MN];
inline void add(int u, int v, int z)
{
j ++;
e[j].to = v;
e[j].val = z;
e[j].next = head[u];
head[u] = j;
}
int main()
{
scanf("%d%d", &n, &m);
for(i = 1; i <= m; i ++)
{
scanf("%d%d%d", &u, &v, &z);
add(u, v, z);//有向图
//or add(u, v, z), add(v, u, z);无向图
}
return 0;
}
- 星形表示的边排序法:特殊用途,如Kruskal算法
星形表示法就是使之可以通过起点或终点定位边。由于很多时候,算法只需事先知道起点,通过枚举边扩展,而不需要事先知道终点;如图的遍历,松弛操作。
#include <bits/stdc++.h>
using namespace std;
const int MN = 1005;
struct info{
int u, v, z;
}e[MN * 4];
int n, m, i, j, u, v, z;
int main()
{
scanf("%d%d", &n, &m);
for(i = 1; i <= m; i ++)
{
scanf("%d%d%d", &u, &v, &z);
e[i].u = u, e[i].v = v, e[i].z = z;//有向图
}
sort(e + 1, e + m + 1, cmp);
return 0;
}
前几天在做基础【水题,接下来一两天做一下图论的,加油~~