最优贸易
。。。看错题了。如果题意理解正确的话还是比较好想的spfa或dij处理i之前和之后的最大最小值,但这多少有点感性。更清楚的是一篇题解里介绍的分层图+spfa的方法。
code
#include<bits/stdc++.h>
#define fi first
#define se second
#define MP make_pair
#define Pit pair<int,int>
using namespace std;
const int N=1e5+5,oo=0x3f3f3f3f;
vector<Pit > G[N*3];
queue<int> Q;
int a[N],in[N*3],dis[N*3];
int n,m;
void add(int x,int y)
{
G[x].push_back(MP(y,0));
G[x+n].push_back(MP(y+n,0));
G[x+n+n].push_back(MP(y+n+n,0));
G[x].push_back(MP(y+n,-a[x]));
G[x+n].push_back(MP(y+n+n,a[x]));
}
void spfa()
{
for(int i=1;i<=n;i++) dis[i]=-oo;
Q.push(1); in[1]=1; dis[1]=0;
while(Q.size())
{
int x=Q.front(); Q.pop();
in[x]=0;
for(auto i:G[x])
if(dis[x]+i.se>dis[i.fi])
{
dis[i.fi]=dis[x]+i.se;
if(!in[i.fi]) { Q.push(i.fi); in[i.fi]=1; }
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",a+i);
for(int i=1;i<=m;i++)
{
int x,y,z; scanf("%d%d%d",&x,&y,&z);
add(x,y);
if(z==2) add(y,x);
}
G[n].push_back(MP(3*n+1,0));
G[n*3].push_back(MP(3*n+1,0));
n=3*n+1;
spfa();
cout<<dis[n]<<endl;
return 0;
}