1. 程式人生 > >3159 Candies(差分約束系統)

3159 Candies(差分約束系統)

題目大意:給出N個孩子,M個要求,問滿足所有孩子的要求時,第一個孩子的糖果和第N個孩子的糖果差的最大值是多少

解題思路:差分約束系統的裸題,B孩子的糖果數量- A孩子的糖果數量 <= C,即d[B] - d[A] <= C,所以可以構出一條A指向B的邊,權值為C
跑一遍SPFA,注意要用棧代替佇列,不然會TLE

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define N 30010
#define M 150010
#define INF 0x3f3f3f3f struct Edge{ int to, dist, next; }E[M]; int head[N], d[N], n, m, tot; int stack[N]; bool vis[N]; void AddEdge(int from, int to, int dist) { E[tot].to = to; E[tot].dist = dist; E[tot].next = head[from]; head[from] = tot++; } void init() { memset(head, - 1
, sizeof(head)); tot = 0; int u, v, d; for (int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &d); AddEdge(u, v, d); } } void SPFA() { for (int i = 2; i <= n; i++) d[i] = INF; d[1] = 0; int top = 0; stack[++top] = 1; vis[1] = true
; while (top) { int u = stack[top--]; for (int i = head[u]; i != -1; i = E[i].next) { int v = E[i].to; if (d[v] > d[u] + E[i].dist) { d[v] = d[u] + E[i].dist; if (!vis[v]) { vis[v] = true; stack[++top] = v; } } } vis[u] = false; } printf("%d\n", d[n]); } int main() { while (scanf("%d%d", &n, &m) != EOF) { init(); SPFA(); } return 0; }