1> 求 1 到所有點的最短路徑,
2> 求 n 到所有點的最長路徑
3> 做差。
看是否可達,判斷是否入過隊。
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAXN 100004
#define INF 0x3f3f3f3f
int dist1[MAXN],dist2[MAXN];
int vis1[MAXN],vis2[MAXN];
int head1[MAXN],head2[MAXN];
int top;
struct Edge{
int to,next;
}edge[MAXN*5];
void addedge(int u,int v){
edge[top].to=v;
edge[top].next=head1[u];
head1[u]=top++;
edge[top].to=u;
edge[top].next=head2[v];
head2[v]=top++;
}
void SPFA1(int st){
memset(vis1,0,sizeof(vis1));
vis1[st]=1;
queue<int>q;
q.push(st);
while(!q.empty()){
int u = q.front();
q.pop();
for(int i=head1[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
dist1[v]=min(dist1[v],dist1[u]);
if(!vis1[v]){
vis1[v]=1;
q.push(v);
}
}
}
}
void SPFA2(int st){
memset(vis2,0,sizeof(vis2));
vis2[st]=1;
queue<int>q;
q.push(st);
while(!q.empty()){
int u = q.front();
q.pop();
for(int i=head2[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
dist2[v]=max(dist2[v],dist2[u]);
if(!vis2[v]){
vis2[v]=1;
q.push(v);
}
}
}
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
memset(head1,-1,sizeof(head1));
memset(head2,-1,sizeof(head2));
top=0;
for(int i=1;i<=n;i++){
scanf("%d",&dist1[i]);
dist2[i]=dist1[i];
}
while(m--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
addedge(a,b);
if(c==2) addedge(b,a);
}
SPFA1(1);
SPFA2(n);
int minn=0;
for(int i=1;i<=n;i++){
if(vis1[i]&&vis2[i])
minn=max(minn,dist2[i]-dist1[i]);
}
printf("%d\n",minn);
}
return 0;
}