以前帮初学的脑洞过这个题
实际上还是多有趣的
问题是这样子的:
你需要买一次(所以这和APIO那个没什么关系)
定义dS为到目前为止从起点到现在最小值
dT为从这里到终点最小值
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+100;
inline void read(int &x){
x=0;
char ch=getchar();
int f=1;
while(ch<'0'||ch>'9'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
struct Front_star{
int u,v,nxt;
}e[N*4];
int cnt=1;
int first[N]={};
void add(int u,int v){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].nxt=first[u];
first[u]=cnt;
}
int n,m;
queue<int> Q;
int dS[N]={};
int dT[N]={};
int vis[N]={};
int val[N]={};
int edge[N][3]={};
//int d1[N]={};
inline void SPFA(){
Q.push(1);
memset(dS,0x3f,sizeof(dS));
while(!Q.empty()){
int x=Q.front();
Q.pop();
vis[x]=0;
for(int i=first[x];i;i=e[i].nxt){
int v=e[i].v;
if(dS[v]>min(dS[x],val[v])){
dS[v]=min(dS[x],val[v]);
if(!vis[v])
Q.push(v),vis[v]=1;
}
}
}
}
inline void SPFA2(){
Q.push(n);
memset(dT,-1,sizeof(dT));
while(!Q.empty()){
int x=Q.front();
Q.pop();
vis[x]=0;
for(int i=first[x];i;i=e[i].nxt){
int v=e[i].v;
if(dT[v]<max(dT[x],val[v])){
dT[v]=max(dT[x],val[v]);
if(!vis[v])
Q.push(v),vis[v]=1;
}
}
}
}
int main(){
read(n);
read(m);
for(int i=1;i<=n;i++){
read(val[i]);
// dS[i]=dT[i]=val[i];
}
for(int i=1;i<=m;i++){
int x,y,z;
read(x);
read(y);
read(z);
edge[i][0]=x;
edge[i][1]=y;
edge[i][2]=z;
add(x,y);
if(z==2)
add(y,x);
}
SPFA();
// cout<<dS[3]<<'\n';
memset(vis,0,sizeof(vis));
memset(first,0,sizeof(first));
cnt=1;
for(int i=1;i<=m;i++){
add(edge[i][1],edge[i][0]);
if(edge[i][2]==2)add(edge[i][0],edge[i][1]);
}
SPFA2();
int ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,dT[i]-dS[i]);
}
cout<<ans;
}