NOIP2009 提高第三题 最佳贸易
2017年7月14日
双向SPFA
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
/*
第一行包含 2 个正整数 n 和 m,中间用一个空格隔开,分别表示城市的数目和道路的数目。
第二行 n 个正整数,每两个整数之间用一个空格隔开,按标号顺序分别表示这 n 个城市的商品价格。
接下来 m 行,每行有 3 个正整数,x,y,z,每两个整数之间用一个空格隔开。如果 z=1,表示这条道路是城市 x 到城市 y 之间的单向道路;如果 z=2,表示这条道路为城市 x 和城市y 之间的双向道路。
*/
const int maxx1 = 110000, maxx2 = 500100;
int N, M;
//分别表示城市的数目和道路的数目;
// 1≤n≤100000,1≤m≤500000;
int price[maxx1];
//正向SPFA
struct Edge_1{
int y; int next;
}F1[maxx2];
int L1[maxx1];
//反向SPFA
struct Edge_2{
int y; int next;
}F2[maxx2];
int L2[maxx1];
int tails1 = 0;
int tails2 = 0;
//
int minDis[maxx1];
int maxDis[maxx1];
bool Jud[maxx1];//Whole
int Que[maxx1];//Whole
int ans = 0, ed = 1;//whole
void Getinto(int a, int b)
{
F1[++tails1].y = b;
F1[tails1].next = L1[a];
L1[a] = tails1;
//
F2[++tails2].y = a;
F2[tails2].next = L2[b];
L2[b] = tails2;
}
void Putin()
{
cin >> N >> M;
memset(F1, 0, sizeof(F1));
memset(F2, 0, sizeof(F2));
for(int i = 1; i <= N; i++)
cin >> price[i];
int xi, yi, zi;
for(int i = 1; i <= M; i++){
cin >> xi >> yi >> zi;
if(zi == 1) Getinto(xi, yi);
else{
Getinto(xi, yi);
Getinto(yi, xi);
}
}
return;
}
void stSPFA()
{
memset(minDis, 10, sizeof(minDis));
memset(Que, -1, sizeof(Que));
memset(Jud, false, sizeof(Jud));
Que[1] = 1; Jud[1] = true; minDis[1] = price[1];
while(ans <= ed)
{
int sgn = Que[++ans]; Jud[sgn] = false;
int lne = L1[sgn];
//sng:队头节点; lne:sng节点的每条边;
for(int i = lne; i; i = F1[i].next)
{
int wto = F1[i].y;//指向的节点;
if(minDis[wto] > min(minDis[sgn], price[wto])){
minDis[wto] = min(minDis[sgn], price[wto]);
if(Jud[wto] == false){
Que[++ed] = wto;
Jud[wto] = true;
}
}
}
}
return;
}
void enSPFA()
{
memset(Que, -1, sizeof(Que));
memset(Jud, false, sizeof(Jud));
memset(maxDis, -1, sizeof(maxDis));
ans = 0; ed = 1;
maxDis[N] = price[N]; Que[1] = N;
Jud[N] = true;
while(ans <= ed)
{
int sgn = Que[++ans]; Jud[sgn] = false;
int lne = L2[sgn];
//sng:队头节点; lne:sng节点的每条边;
for(int i = lne; i; i = F2[i].next)
{
int wto = F2[i].y;
if(maxDis[wto] < max(maxDis[sgn], price[wto]))
{
maxDis[wto] = max(maxDis[sgn], price[wto]);
if(Jud[wto] == false){
Que[++ed] = wto;
Jud[wto] = true;
}
}
}
}
return;
}
void Find()
{
int maxans = -1;//城市最大差价
for(int i = 1; i <= N; i++)
{
if(maxDis[i] == -1 || minDis[i] > 1000)
continue;
maxans = max(maxans, (maxDis[i] - minDis[i]));
}
if(maxans <= 0) cout << 0 << endl;
else cout << maxans <<endl;
}
int main()
{
Putin();
stSPFA();
enSPFA();
Find();
return 0;
}