您的位置:首页 > 其它

NOIP 2009 最优贸易 解题报告

2011-08-13 23:50 330 查看
  就实现正向从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;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: