Bellman-ford 模板
单源最短路是固定一个起点到其他个所有点的最短路。终点也固定的最短路是双源最短路,但是由于解题的复杂度和单源最短路的复杂度一样,所以就可以当做单源最短路来做。
记从起点s出发到顶点i的最短距离为d[i],则下述表示会成立。
d[i] = min{q[j]+(从j到i的边权)|e∈E(i,j)}
如果是DAG(有向无环图),就可以按拓扑序给顶点编号,并利用这条递归关系计算出d.如果图中有圈,就无法依赖这个关系直接计算。在这种情况下,记起点为s,d[s] = 0,d[i] = INF 在利用上述递推关系公式求出。
也就是说不管有没有环,都可以让d[s] =0,d[i] = INF 再利用上述关系式去求。
例题:(自己编的,帮助理解)
给定一个联通图。有v个点,e条边。每条边都有权值,求最路径。
输入:
4 4
1 2 1
2 3 3
1 4 2
4 3 4
//
// Created by luozujian on 17-10-13.
//
//最短路算法
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
using namespace std;
const int maxv = 1e2+5;
const int maxe = 1e2+5;
struct edge{
int from,to,cost;
};
edge es[maxe];
int d[maxv];
int e,v;
void Bellman_ford(int s)
{
for(int i=1;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;
}
}
void solve()
{
Bellman_ford(1);
printf("%d\n",d[4]);
}
int main()
{
scanf("%d%d",&v,&e);
for(int i=0;i<e;i++)
{
int s,t,cost;
scanf("%d%d%d",&s,&t,&cost);
es[i].from = s;
es[i].to = t;
es[i].cost = cost;
}
solve();
return 0;
}
/* 4 4 1 2 1 2 3 3 1 4 2 4 3 4 */