基础图论知识总结
Posted 77458
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基础图论知识总结相关的知识,希望对你有一定的参考价值。
1. 最短路
何为最短路?
给定两个顶点,在以这两个点为起点和终点的路径中,边的权值和最小的路径即为最短路
何为单源最短路?何为两点之间的最短路?
固定一个起点,求它到其他所有点的最短路的问题,终点也固定的问题叫做两点之间的最短路问题
Bellman−Ford 算法
记从起点
S
出发到顶点
其中 cost(i,j) 表示路径 e(i,j) 的花费
对于给定的初始化起点
S
,我们设初值
时间复杂度为
const int INF = 0x3f3f3f3f;
const int MAXN = 1e3 + 5;
struct edge
int from, to, cost;
edge es[MAXN];//边
int d[MAXN];//最短距离
int V, E;//V是顶点数,E是边数
//求解顶点s到所有点的最短距离
void shortest_path(int s)
memset(d, 0x3f, sizeof(d));
d[s] = 0;//初始位置最短距离即为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;
如果要检查负环,则要对 d[i] 初始化为 0 ,可以检查出所有的负环
时间复杂度为
//返回true则存在负环
bool find_negative_loop()
memset(d, 0, sizeof(d));
for(int i = 0;i < V;i ++)
for(int j = 0;j < E;j ++)
edge e = es[j];
if(d[e.to] > d[e.from] + e.cost)
d[e.to] = d[e.from] + e.cost;
//如果第n次仍然更新了,则存在负环
if(i == V - 1) return true;
return false;
Dijkstra 算法
基于 Bellman−Ford 算法进行优化,做如下修改:
找到最短距离已经确定的顶点,从它出发更新相邻顶点的最短距离
此后不需要关系 1 中”最短距离已经确定的顶点”
用邻接矩阵实现的
时间复杂度为
O(|E|×log|V|)
const int MAXN = 1e3 + 5;
const int INF = 0x3f3f3f3f;
struct edge
int to, cost;
typedef pair<int, int >PII;//first是最短距离,second是顶点的编号
int V;
vector<edge>G[MAXN];
int d[MAXN];
void dijkstra(int s)
//通过制定greater<PII>参数,堆按照first从小到大的顺序取出值
priority_queue<PII, vector<PII>, greater<PII> >que;
memset(d, 0x3f, sizeof(d));
d[s] = 0;
que.push(PII(0, s));
while(!que.empty())
PII e = que.top();
que.pop();
int v = e.second;
if(d[v] < e.first) continue;//如果取出的不是最短距离则继续取
for(int i = 0;i < G[v].size();i ++)
edge e = G[v][i];
if(d[e.to] > d[v] + e.cost)
d[e.to] = d[v] + e.cost;
que.push(PII(d[e.to], e.to));
如果存在负边,则还需使用 Bellman−Ford 算法
Floyd−Warshall 算法
作用:任意两点之间的最短路问题
列出状态转移方程:
可以处理负数即负边,而判断图中是否有负环,只需检查是否存在 d[i][i] 是负数的顶点 i 就可以了
int d[MAXN][MAXN];//d[v][u]表示边e=(u,v)的权值(不存在时舍为INF, 不过d[i][i]=0)
int V;//顶点数
void warshall_floyd()
for(int k = 0;k < V;k ++)
for(int i = 0;i < V;i ++)
for(int j = 0;j < V;j ++)
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
路径还原
在求解最短距离时,满足