此题主要考察的是思想,可以借助最短路的思想去做,我写的是dijkstra,通过每次找中间点的方式,两次操作(请读者慢慢思考)
而两次操作一次跑的是题目上给的边,第二次跑的是反向边,请读者好好思考
而既然借助dijkstra的思想,每次找点,请注意,此坑本作者语文能力有限,无法讲解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; inline int read() { int f=1,ans=0;char c; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return ans*f; } int n,m,s[100001],dis1[100001],dis2[100001],head1[100001],head2[100001],cnt1,cnt2,vis1[100001],vis2[100001]; struct node{ int u,v,nex; }x1[1000001]; struct node1{ int u,v,nex; }x2[1000001]; void add1(int u,int v) { x1[cnt1].u=u,x1[cnt1].v=v,x1[cnt1].nex=head1[u],head1[u]=cnt1++; swap(u,v); x2[cnt2].u=u,x2[cnt2].v=v,x2[cnt2].nex=head2[u],head2[u]=cnt2++; } void add2(int u,int v) { x1[cnt1].u=u,x1[cnt1].v=v,x1[cnt1].nex=head1[u],head1[u]=cnt1++; swap(u,v); x1[cnt1].u=u,x1[cnt1].v=v,x1[cnt1].nex=head1[u],head1[u]=cnt1++; swap(u,v); x2[cnt2].u=u,x2[cnt2].v=v,x2[cnt2].nex=head2[u],head2[u]=cnt2++; swap(u,v); x2[cnt2].u=u,x2[cnt2].v=v,x2[cnt2].nex=head2[u],head2[u]=cnt2++; } priority_queue<pair< int , int > > que1; priority_queue<pair< int , int > > que2; int main() { memset(head1,-1,sizeof(head1)),memset(head2,-1,sizeof(head2)); n=read(),m=read(); for(int i=1;i<=n;i++) s[i]=read(); for(int i=1;i<=m;i++) { int u=read(),v=read(),w=read(); if(w==1) add1(u,v); else add2(u,v); } dis1[1]=s[1]; que1.push(make_pair(0,1)); while(!que1.empty()) { int xx=que1.top().second;que1.pop(); if(vis1[xx]==1) continue; vis1[xx]=1; for(int i=head1[xx];i!=-1;i=x1[i].nex) { que1.push(make_pair(-min(dis1[x1[i].u],s[x1[i].v]),x1[i].v)); dis1[x1[i].v]=min(dis1[x1[i].u],s[x1[i].v]); } } dis2[n]=s[n]; que2.push(make_pair(0,n)); while(!que2.empty()) { int xx=que2.top().second;que2.pop(); if(vis2[xx]==1) continue; vis2[xx]=1; for(int i=head2[xx];i!=-1;i=x2[i].nex) { que2.push(make_pair(-max(dis2[x2[i].u],s[x2[i].v]),x2[i].v)); dis2[x2[i].v]=max(dis2[x2[i].u],s[x2[i].v]); } } int maxn=-(2<<30-1); for(int i=1;i<=n;i++) maxn=max(maxn,dis2[i]-dis1[i]); cout<<maxn; }