传送门
题意: 给定n个限制关系u v w表示u认为v的糖果数量最多比它多w个. 问在满足这些的条件下, 1与n的糖果数量最大的差是多少.
思路: 知道差分约束的很容易可以判断出这个是差分约束, 我们用d数组表示一个人拥有的糖果数量那么结合题意就有d[u] + w >= d[v], 也就是类似于最短路中的松弛条件dis[u] + g[u][v] <= dis[v], 只是形式上有点不同, 但是它的实际意思却是很相似的, 所以我们u - v 连一条权值为w的边, 所以求1 - n最大差(最大值)也就是跑1 - n 的最短路即是ans.
(不懂的建议先学学差分约束)
AC Code
const int maxm = 2e5 + 5;
int n, m;
struct node
{
int to, next, w;
bool operator < (const node& a) const {
return w > a.w;
}
} e[maxm];
int cnt, head[maxn];
void add(int u, int v,int w) {
e[cnt] = (node){v, head[u], w};
head[u] = cnt++;
}
void init() {
cnt = 0;
Fill(head, -1);
}
bool vis[maxn];
int dis[maxn];
void dij(int st,int ed)
{
priority_queue<node> q;
Fill(dis,inf); Fill(vis,0);
dis[st] = 0;
q.push((node){st, 0, 0});
while (!q.empty()) {
node u = q.top();
q.pop();
if(vis[u.to]) continue;
vis[u.to] = 1;
for (int i = head[u.to]; ~i; i = e[i].next) {
int to = e[i].to;
if (dis[to] > dis[u.to] + e[i].w) {
dis[to] = dis[u.to] + e[i].w;
q.push((node){to, 0, dis[to]});
}
}
}
cout << dis[ed] << endl;
}
void solve()
{
scanf("%d%d", &n, &m);
init();
for (int i = 1 ; i <= m ; i ++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
}
dij(1, n);
}