There are many troublesome methods on the Internet, here is the simplest one
设disi dis_idisiRepresents 1 11 arrivaliiThe smallest point weight (crystal ball price) on all paths of i ,disti dist_idistiDisplay iii tonnThe maximum point weight on all paths of n .
So, the final answer ismax i = 1 n {disti − disi} \max\limits_{i=1}^n \{dist_i-dis_i\}i=1maxn{
disti−disi}
Because each point can go through multiple times, SPFA is used
#include<cstdio>
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int Maxn=100000+10,inf=0x3f3f3f3f;
vector <int> e[Maxn],g[Maxn];
int a[Maxn],dis[Maxn],dist[Maxn];
int n,m,ans;
bool vis[Maxn];
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
void spfa1()
{
fill(dis+1,dis+1+n,inf);
queue <int> q;
vis[1]=1,dis[1]=a[1];
q.push(1);
while(q.size())
{
int x=q.front();
q.pop();
vis[x]=0;
for(int i=0;i<e[x].size();++i)
{
int y=e[x][i];
if(dis[y]>min(dis[x],a[y]))
{
dis[y]=min(dis[x],a[y]);
if(!vis[y])vis[y]=1,q.push(y);
}
}
}
}
void spfa2()
{
fill(dist+1,dist+1+n,-inf);
queue <int> q;
vis[n]=1,dist[n]=a[n];
q.push(n);
while(q.size())
{
int x=q.front();
q.pop();
vis[x]=0;
for(int i=0;i<g[x].size();++i)
{
int y=g[x][i];
if(dist[y]<max(dist[x],a[y]))
{
dist[y]=max(dist[x],a[y]);
if(!vis[y])vis[y]=1,q.push(y);
}
}
}
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;++i)
a[i]=read();
for(int i=1;i<=m;++i)
{
int x=read(),y=read(),opt=read();
e[x].push_back(y);
g[y].push_back(x);
if(opt==2)
{
e[y].push_back(x);
g[x].push_back(y);
}
}
spfa1();
spfa2();
for(int i=1;i<=n;++i)
ans=max(ans,dist[i]-dis[i]);
printf("%d\n",ans);
return 0;
}