dijkstra
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
int n, m, s, a, b, c;
const int MAXN = 100010;
struct edge
{
int v, w; // 点,边权
};
struct node
{
int dis, u; // 距离,点
bool operator>(const node &a) const
{
return dis > a.dis;
}
};
vector<edge> e[MAXN];
int dis[MAXN], vis[MAXN];
priority_queue<node, vector<node>, greater<node>> q; // q{dis,u}
void dijkstra(int n, int s)
{
memset(dis, 0x3f, (n + 1) * sizeof(int));
memset(vis, 0, (n + 1) * sizeof(int));
dis[s] = 0;
q.push({0, s});
while (!q.empty())
{
int u = q.top().u;
q.pop();
if (vis[u])
continue;
vis[u] = 1;
for (auto ed : e[u])
{
int v = ed.v, w = ed.w;
if (dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
q.push({dis[v], v});
}
}
}
}
int main()
{
cin >> n >> m >> s;
for (int i = 0; i < m; i++)
{
cin >> a >> b >> c;
e[a].push_back({b, c});
}
dijkstra(n, s);
for (int i = 1; i <= n; i++)
cout << dis[i] << " ";
return 0;
}
P4779 [模板]单源最短路径
SPFA
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 1000010;
int n, m;
struct edge
{
int v, w;
};
vector<edge> e[MAXN];
int dis[MAXN], cnt[MAXN], vis[MAXN];
queue<int> q;
bool spfa(int n, int s)
{
memset(dis, 0x3f, (n + 1) * sizeof(int));
memset(cnt, 0, (n + 1) * sizeof(int));
memset(vis, 0, (n + 1) * sizeof(int));
dis[s] = 0, vis[s] = 1;
q.push(s);
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0; // 出队后取消标记
for (auto ed : e[u])
{
int v = ed.v, w = ed.w;
if (dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
cnt[v] = cnt[u] + 1; // 最短路经过的边数
if (cnt[v] >= n) // 最短路边数大于等于n显然有负环
return false;
if (!vis[v])
{
q.push(v);
vis[v] = 1;
}
}
}
}
return true;
}
int main()
{
int T;
cin >> T;
while (T--)
{
memset(e, 0, sizeof(e));
int u, v, w;
cin >> n >> m;
for (int i = 0; i < m; i++)
{
cin >> u >> v >> w;
e[u].push_back({v, w});
if (w >= 0)
e[v].push_back({u, w});
}
if (!spfa(n, 1))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
P3385 [模板]负环
Johnson
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
#define INF 1e9
const int MAXN = 30005;
int n, m;
struct edge
{
int v, w;
};
struct node
{
long long dis;
int u; // 距离,点
bool operator>(const node &a) const
{
return dis > a.dis;
}
};
vector<edge> e[MAXN];
long long d[MAXN], cnt[MAXN], vis[MAXN], h[MAXN];
bool spfa(int s)
{
queue<int> q;
memset(h, 0x3f, sizeof(h));
memset(cnt, 0, sizeof(cnt));
memset(vis, 0, sizeof(vis));
h[s] = 0, vis[s] = 1;
q.push(s);
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0; // 出队后取消标记
for (auto ed : e[u])
{
int v = ed.v, w = ed.w;
if (h[v] > h[u] + w)
{
h[v] = h[u] + w;
cnt[v] = cnt[u] + 1; // 最短路经过的边数
if (cnt[v] > n) // 最短路边数大于等于n显然有负环
return false;
if (!vis[v])
{
q.push(v);
vis[v] = 1;
}
}
}
}
return true;
}
void dijkstra(int s)
{
priority_queue<node, vector<node>, greater<node>> q; // q{dis,u}
for (int i = 1; i <= n; i++)
d[i] = INF; // 不能用memset
memset(vis, 0, sizeof(vis));
d[s] = 0;
q.push({0, s});
while (!q.empty())
{
int u = q.top().u;
q.pop();
if (vis[u])
continue;
vis[u] = 1;
for (auto ed : e[u])
{
int v = ed.v, w = ed.w;
if (d[v] > d[u] + w)
{
d[v] = d[u] + w;
q.push({d[v], v});
}
}
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
e[a].push_back({b, c});
}
for (int i = 1; i <= n; i++)
e[0].push_back({i, 0}); // 加虚拟源点0
if (!spfa(0))
{
cout << -1 << endl;
return 0;
}
for (int u = 1; u <= n; u++)
for (auto &ed : e[u])
ed.w += h[u] - h[ed.v]; // 改造边权,使其非负(三角形法则)
for (int i = 1; i <= n; i++)
{
dijkstra(i);
long long ans = 0;
for (int j = 1; j <= n; j++)
{
if (d[j] == INF)
ans += (long long)j * INF;
else
ans += (long long)j * (d[j] + h[j] - h[i]);
}
cout << ans << endl;
}
return 0;
}
P5905 [模板]全源最短路