📅  最后修改于: 2023-12-03 15:37:17.002000             🧑  作者: Mango
图论是数学的一个分支,研究的是图和网络的有关性质和算法。图是由一些点和连接它们的线(边)组成的。图论主题包括:图的嵌入、图的着色、图的最大独立集、图的最优化、特殊类型的图、网络流等。
// Dijkstra算法示例代码
const int MAXV = 1001;
const int INF = INT_MAX; // 无穷大
int n; // 图的节点总数
int graph[MAXV][MAXV]; // 图的邻接矩阵
int d[MAXV]; // 保存到各个节点的最短距离
bool used[MAXV]; // 是否已经计算出了最短距离
void dijkstra(int s) {
fill(d, d + MAXV, INF); // 初始化距离
fill(used, used + MAXV, false);
d[s] = 0; // 源点到源点的距离为0
while (true) {
int v = -1;
for (int u = 0; u < n; u++) {
if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
}
if (v == -1) break;
used[v] = true;
for (int u = 0; u < n; u++) {
d[u] = min(d[u], d[v] + graph[v][u]);
}
}
}
// Bellman-Ford算法示例代码
struct edge { int from, to, cost; };
edge es[MAXE];
int d[MAXV]; // 保存到各个节点的最短距离
int V, E;
void bellman_ford(int s) {
for (int i = 0; i < V; i++)
d[i] = INF;
d[s] = 0;
while (true) {
bool update = false;
for (int i = 0; i < E; i++) {
edge e = es[i];
if (d[e.from] != INF && d[e.to] > d[e.from] + e.cost) {
d[e.to] = d[e.from] + e.cost;
update = true;
}
}
if (!update) break;
}
}
// Prim算法示例代码
const int MAXV = 1001;
const int INF = INT_MAX;
int n;
int graph[MAXV][MAXV]; // 图的邻接矩阵
int d[MAXV]; // 记录到树中每个节点的距离
bool used[MAXV]; // 已经加入树中的点
int prim() {
fill(d, d + MAXV, INF);
fill(used, used + MAXV, false);
d[0] = 0; // 从0号节点开始
int res = 0; // 最小生成树的边权和
while (true) {
int v = -1;
// 选择距离树最近的边
for (int u = 0; u < n; u++) {
if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
}
if (v == -1) break;
used[v] = true;
res += d[v];
// 更新到树中每个节点的距离
for (int u = 0; u < n; u++) {
d[u] = min(d[u], graph[v][u]);
}
}
return res;
}
// Kruskal算法示例代码
struct edge { int u, v, cost; };
edge es[MAXE];
int V, E;
int uf[MAXV];
bool cmp(const edge& a, const edge& b) {
return a.cost < b.cost;
}
int kruskal() {
sort(es, es + E, cmp);
init_union_find(V);
int res = 0;
for (int i = 0; i < E; i++) {
edge e = es[i];
if (!same(e.u, e.v)) {
unite(e.u, e.v);
res += e.cost;
}
}
return res;
}
图论是算法中一道非常重要的题目,通过学习和掌握常用的算法,可以大大提升程序员的算法竞赛水平。同时,熟悉常用工具和资源,也能使工作和学习更加便捷。
参考资料: