接下来讲具体解法。
第一、输入。存邻接表
第二、我们需要做深搜。可以用递归来做,同时做动规:
函数如下(贴了注释).
void dfs(int x,int minx,int pre) { //x表示当前访问的节点编号,minx表示目前为止的最小的商品价格,pre表示上一个节点的编号
int flag=1; //用于判断是否已被访问过,需要终止
minx=min(c[x],minx); //判断本次的商品价格是否是最小值
if (mi[x]>minx) mi[x]=minx,flag=0; //判断mi数组(记录了每次的最小值)并更新,在更新的同时把flag设为0(不用退出了)
做动态规划; //别着急flag还会继续更新的
if (flag) return; //退出,千万不能露,不然程序就会放飞自我,堆栈溢出->完美MLE只有10分。
for (int i=0;i<g[x].size();i++) dfs(g[x][i],minx,x); //继续进行递归调用,访问目前节点能访问到的节点。
}
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x7f7f7f7f
const int N=1e5+10;
vector<int>v[N];
int n,m,f[N],mi[N],c[N];
void init(){
for(int i=1;i<=n;i++)mi[i]=inf;
}
void dfs(int x,int minx,int pre){
int flag=1;
minx=min(c[x],minx);
if(mi[x]>minx){
mi[x]=minx;
flag=0;
}
int mmax=max(f[pre],c[x]-minx);
if(f[x]<mmax){
f[x]=mmax;
flag=0;
}
if(flag)return;
for(auto i:v[x]){
dfs(i,minx,x);
}
}
void solve() {
cin>>n>>m;
init();
for(int i=1;i<=n;i++) cin>>c[i];
for(int i=1;i<=m;i++){
int x,y,z;
cin>>x>>y>>z;
v[x].push_back(y);
if(z==2) v[y].push_back(x);
}
dfs(1,inf,0);
cout<<f[n]<<"\n";
}
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int tt=1;
//cin>>tt;
while(tt--) {
solve();
}
return 0;
}