利用最短路的松弛特性,保证了差分约束中的B <= A + c,即d[v] <= d[u] + w,因此建立从A--B的一条边,边权为c即可,最终求从1-n的最短路即符合所有情况的最小总和,同理可以用最长路解决差分约束问题
什么是差分约束: https://www.cnblogs.com/zhangmingcheng/p/3929394.html
dijkstra+优先队列快很多
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#define ll long long
#define mod 1000000007
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 30005;
int head[maxn];
int d[maxn];
bool vis[maxn];
int cnt;
struct edge
{
int to, next, w;
}e[200005];
struct node
{
int v, c;
friend bool operator < (const node &a, const node &b)
{
return a.c > b.c;
}
node(int x = 0, int y = 0) : v(x), c(y) {}
};
void addedge(int u, int v, int w)
{
e[cnt].w = w;
e[cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt ++;
}
void init()
{
memset(head, -1, sizeof(head));
cnt = 0;
memset(d, 0x3f, sizeof(d));
memset(vis, 0, sizeof(vis));
}
void dijs()
{
priority_queue<node> q;
d[1] = 0;
node h;
q.push(node(1, 0));
while(! q.empty())
{
h = q.top();
q.pop();
int u = h.v;
if(vis[u]) continue;
vis[u] = 1;
for(int i = head[u]; ~i; i = e[i].next)
{
int v = e[i].to;
int w = e[i].w;
if(! vis[v] && d[v] > d[u] + w)
{
d[v] = d[u] + w;
q.push(node(v, d[v]));
}
}
}
}
int main()
{
int n, m;
while(scanf("%d%d", &n, &m) != EOF)
{
init();
int u, v, w;
for(int i = 1; i <= m; i ++)
{
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w);
}
dijs();
printf("%d\n", d[n]);
}
return 0;
}