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;
}

  

posted @ 2011-08-13 23:50  zqynux  阅读(2508)  评论(0编辑  收藏  举报