NOIP 2009 最优贸易 解题报告
就实现正向从1点出发SPFA,获得min[i],就是到达i点能最低购买到的价格,然后反向(将图反向),从n点开始SPFA,获得max[i],就是从i点到终点能够卖出的最大的价格,然后就是寻找差价最大的i,输出答案即可。
#include <stdio.h> #include <stdlib.h> int num[100000]; int map[1000000], next[1000000]; int end; int head[100000]; void add(int a, int b) { map[end] = b; next[end] = head[a]; head[a] = end++; } int map2[1000000], next2[1000000]; int end2; int head2[100000]; void add2(int a, int b) { map2[end2] = b; next2[end2] = head2[a]; head2[a] = end2++; } #define Q_MAX 100000 int used[100000]; int queue[Q_MAX]; int h, r; void enqueue(int k) { if(used[k]){ return; } used[k] = 1; queue[r] = k; r = (r + 1) % Q_MAX; } int exqueue(void) { int t; t = queue[h]; used[t] = 0; h = (h + 1) % Q_MAX; return t; } int min[100000]; int max[100000]; int main(int argc, char **argv) { int i, j; int n, m; int a, b, c; scanf("%d%d", &n, &m); for(i = 0; i < n; i++){ head[i] = head2[i] = -1; max[i] = -100000; min[i] = 0xFFFFFFF; scanf("%d", &num[i]); } for(i = 0; i < m; i++){ scanf("%d%d%d", &a, &b, &c); a--, b--; if(c == 2){ add(a, b); add(b, a); add2(a, b); add2(b, a); }else{ add(a, b); add2(b, a); } } min[0] = num[0]; enqueue(0); while(h != r){ i = exqueue(); for(a = head[i]; a != -1; a = next[a]){ j = map[a]; if(min[j] > min[i]){ min[j] = min[i]; enqueue(j); } if(min[j] > num[j]){ min[j] = num[j]; enqueue(j); } } } max[n - 1] = num[n - 1]; enqueue(n - 1); while(h != r){ i = exqueue(); for(a = head2[i]; a != -1; a = next2[a]){ j = map2[a]; if(max[j] < max[i]){ max[j] = max[i]; enqueue(j); } if(max[j] < num[j]){ max[j] = num[j]; enqueue(j); } } } for(i = a = 0; i < n; i++){ if(a < max[i] - min[i]){ a = max[i] - min[i]; } } printf("%d\n", a); return 0; }