poj 3159 Candies 差分约束
设a[i] 为第i个小孩得到的糖果数,d[i] 为第i个小孩相对于第1个小孩的糖果数,即有:
d[i] = a[i] – a[1], d[1] = 0.
题目输入的A B c 有: a[B] – a[A] <= c 即有 (a[B] – a[1]) – (a[A] – a[1]) <= c , d[B] – d[A] <= c
题目是求最大值,就是求以1为源点的最短路。
注意:用spfa+队列会tlm, 要改用stack才过, 700ms。试用了Dijkstra+priority_queue,1400+ms擦过去了,不知是不是写得不够好.
#include <iostream> #include <queue> #include <stack> using namespace std; const int MAX = 30005; const int INF = 1000000000; const int N = 150005; struct Node { int v; int cost; int next; }; Node node[N]; int d[MAX]; int adj[MAX]; bool in_q[MAX]; int cnt[MAX]; int size; int n, m; void add_edge(int u, int v, int cost) { node[size].v = v; node[size].cost = cost; node[size].next = adj[u]; adj[u] = size++; } struct cmp { bool operator() (const int &a, const int &b) { return d[a] > d[b]; } }; priority_queue<int, vector<int>, cmp> Q; void Dijkstra() { for (int i = 0; i <= n; i++) d[i] = INF; Q.push(1); d[1] = 0; int u, v, w; while (!Q.empty()) { u = Q.top(); Q.pop(); for (int i = adj[u]; i != -1; i = node[i].next) { v = node[i].v; w = node[i].cost; if (d[v] > d[u] + w) { d[v] = d[u] + w; Q.push(v); } } } } void spfa() { memset(in_q, false, sizeof(in_q)); for (int i = 1; i <= n; i++) d[i] = INF; stack<int> S; d[1] = 0; S.push(1); in_q[1] = true; int u, v, w; while (!S.empty()) { u = S.top(); S.pop(); in_q[u] = false; for (int i = adj[u]; i != -1; i = node[i].next) { v = node[i].v; w = node[i].cost; if (d[v] > d[u] + w) { d[v] = d[u] + w; if (!in_q[v]) { in_q[v] = true; S.push(v); } } } } } int main() { int a, b, w; scanf("%d%d", &n, &m); for (int i = 0; i <= n; i++) adj[i] = -1; for (int i = 0; i < m; i++) { scanf("%d%d%d", &a, &b, &w); add_edge(a, b, w); } Dijkstra(); printf("%d\n", d[n]); return 0; }