中文题目,题意略。
题解:可以考虑烤鱼一个点i,从1~i买入,从i~n的路上售出。所以我们可以维护数组dis1[x]从1到x的路径的最小点权值,然后从dis2[x]维护从x到n的路径上的点的最大权值。维护数组可以通过spfa来维护,最后在枚举i就可以了。
code:
#include<bits/stdc++.h> using namespace std; const int N=1e5+7; const int INF=200; vector<int >ve[N],ve1[N]; int arr[N]; int n,m; int dis1[N],dis2[N]; bool mark1[N],mark2[N]; void spfa1(){ mark1[1]=1; queue<int>que; que.push(1); dis1[1]=arr[1]; while(que.size()){ int u=que.front(); que.pop(); mark1[u]=0; for(int i=0;i<ve[u].size();i++){ if(dis1[u]<dis1[ve[u][i]]||arr[ve[u][i]]<dis1[ve[u][i]]){ dis1[ve[u][i]]=min(dis1[u],arr[ve[u][i]]); if(!mark1[ve[u][i]]){ mark1[ve[u][i]]=1; que.push(ve[u][i]); } } } } } void spfa2(){ mark2[n]=1; queue<int>que; que.push(n); dis2[n]=arr[n]; while(que.size()){ int u=que.front(); que.pop(); mark2[u]=0; for(int i=0;i<ve1[u].size();i++){ if(dis2[u]>dis2[ve1[u][i]]||dis2[ve1[u][i]]<arr[ve1[u][i]]){ dis2[ve1[u][i]]=max(dis2[u],arr[ve1[u][i]]); if(!mark2[ve1[u][i]]){ mark2[ve1[u][i]]=1; que.push(ve1[u][i]); } } } } } int main(){ cin>>n>>m; for(int i=1;i<=n;i++) { cin>>arr[i]; dis1[i]=INF; } int x,y,z; for(int i=1;i<=m;i++){ cin>>x>>y>>z; if(z==1){ ve[x].push_back(y); ve1[y].push_back(x); } else{ ve[x].push_back(y); ve[y].push_back(x); ve1[x].push_back(y); ve1[y].push_back(x); } } spfa1();spfa2(); int ans=0; for(int i=1;i<=n;i++){ ans=max(dis2[i]-dis1[i],ans); } cout<<ans<<endl; return 0; }