最短路模板
(1)无负权边单源最短路 堆优化dijkstra
#include<cstdio>
#include<vector>
#include<queue>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
const int MAXN = 11234;
struct node
{
int u, w;
node(int u = 0, int w = 0) : u(u), w(w) {};
bool operator < (const node& rhs) const
{
return w > rhs.w; //注意这里是大于,因为要小跟堆
}
};
vector<node> g[MAXN];
int d[MAXN], n, m;
int work()
{
priority_queue<node> q;
REP(i, 1, n + 1) d[i] = (i == 1 ? 0 : 1e9); //注意这里i等于1的时候为0
q.push(node(1, 0)); //加入一开始的边
while(!q.empty())
{
node x = q.top(); q.pop();
int u = x.u;
if(d[u] != x.w) continue;
REP(i, 0, g[u].size())
{
int v = g[u][i].u, w = g[u][i].w;
if(d[v] > d[u] + w)
{
d[v] = d[u] + w;
q.push(node(v, d[v]));
}
}
}
return d[n];
}
int main()
{
scanf("%d%d", &n, &m);
while(m--)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
g[u].push_back(node(v, w));
g[v].push_back(node(u, w));
}
printf("%d\n", work());
return 0;
}
(2)任意两点间最短路 Floyd
//初始化
REP(i, 0, n)
REP(j, 0, n)
d[i][j] = (i == j ? 0 : 1e9);
//Floyd
REP(k, 0, n)
REP(i, 0, n)
REP(j, 0, n)
if(d[i][k] != 1e9 && d[k][j] != 1e9)
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
// d[i][j] |= (d[i][k] && d[k][j]) 判断联通
(3)可有负权变单源最短路SPFA(可以用来判断负环)
#include<cstdio>
#include<vector>
#include<queue>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
const int MAXN = 11234;
struct node
{
int v, w;
node(int v = 0, int w = 0) : v(v), w(w) {}
};
vector<node> g[MAXN];
int d[MAXN], vis[MAXN], cnt[MAXN], n, m;
int work()
{
queue<int> q;
REP(i, 1, n + 1) d[i] = (i == 1 ? 0 : 1e9);
vis[1] = 1;
q.push(1);
while(!q.empty())
{
int u = q.front();
q.pop(); vis[u] = 0;
REP(i, 0, g[u].size())
{
int v = g[u][i].v, w = g[u][i].w;
if(d[v] > d[u] + w)
{
d[v] = d[u] + w;
if(!vis[v])
{
vis[v] = 1;
q.push(v);
if(++cnt[v] > n) return -1;//关键!可以判断负环
}
}
}
}
return d[n];
}
int main()
{
scanf("%d%d", &n, &m);
while(m--)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
g[u].push_back(node(v, w));
g[v].push_back(node(u, w));
}
printf("%d\n", work());
return 0;
}
其实spfa和dijkstra非常像, dijkstra是每次找一个最近的点入队, 然后去松弛。而spfa是一个点可以入很多次, 每次都去松弛。