后期再补齐原理,先说一下局限性,就是图中不得有自边和负边权
//Dijkstra升级版 可以处理负边权
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <unordered_map>
using namespace std;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const long long N = 1e5 + 10, M = 2e6 + 10;
long long n, m, s;
struct Node
{
long long to;
long long weight;
};
Node NNN;
vector<Node> g[N];
bool vis[N];
long long d[N];
long long d1[N];
// 点u, d[u]
struct VNode
{
long long p;
long long d;
bool operator<(const VNode &b) const
{
return d > b.d;
}
};
VNode NNNN;
void dijkstra(long long s)
{
priority_queue<VNode> q;
for (long long i = 1; i <= n; i++)
{
d[i] = INF;
}
d[s] = 0;
NNNN.p = s;
NNNN.d = 0;
q.push(NNNN);
while (!q.empty())
{
long long u = q.top().p; // 找到堆顶元素
q.pop();
if (vis[u]) // 如果已经找到了, 就不要再操作了
{
continue;
}
// 如果已经在S集合中了, 就不要操作了, 只有在T集合中的点, 我们才
// 拿进去, 然后松弛
vis[u] = 1;
for (auto e : g[u])
{
long long v = e.to;
long long w = e.weight;
if (vis[v] == 0 && d[v] > d[u] + w)
{
//cout << v << endl;
d1[v] = 1 + d1[u]; //
d[v] = d[u] + w;
NNNN.p = v;
NNNN.d = d[v];
q.push(NNNN);
}
}
}
}
long long tigao = INF;
signed main()
{
cin >> n >> m >> s;
for (long long i = 1; i <= m; i++)
{
long long u, v, w;
cin >> u >> v >> w;
NNN.to = v;
NNN.weight = w;
g[u].push_back(NNN);
tigao = w < 0 ? min(tigao, w) : tigao;
}
if (tigao != INF)
{
tigao = 1 - tigao;
for (long long i = 1; i <= n; i++)
{
for (auto &j : g[i])
{
j.weight += tigao;
// cout<<j.weight<<endl;
}
}
}
else
tigao = 0;
dijkstra(s);
for (long long i = 1; i <= n; i++)
{
if (d[i] == INF){cout << "NO"<< " ";continue;}
cout << d[i] - d1[i] * tigao << endl;
}
return 0;
}