本题甚水,可做也。
从1号城市出发,由于最终要到达n号城市,所以我们不妨可以做反向边,然后从n号城市出发,找到最终可以n号城市的城市,简单明了啊(#^.^#)这样我们只需要走到标记过的城市即可。
然后,我懒得打太麻烦了。就仔细地想了想,发现每个城市走的次数不可能超过两次,于是就打了个简单的bfs,过了。
上标:
#include<cstdio>
#include<algorithm>
using namespace std;
struct node{int v,fr;}e[500010],g[500010];
int n,m,a[100010],tail[100010],head[100010],cnt=0,tot=0;
int f[500010],l,r,d[100010],bz[100010],ans=0;
inline int read()
{
int x=0; char c=getchar();
while (c<'0' || c>'9') c=getchar();
while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x;
}
void add(int u,int v) {e[++cnt]=(node){v,tail[u]}; tail[u]=cnt;}
void add2(int u,int v) {g[++tot]=(node){v,head[u]}; head[u]=tot;}
int main()
{
freopen("trade.in","r",stdin);
// freopen("trade.out","w",stdout);
n=read(),m=read();
for (int i=1;i<=n;i++) d[i]=a[i]=read();
for (int i=1,u,v;i<=m;i++)
{
u=read(),v=read(),add(u,v),add2(v,u);
if (read()==2) add(v,u),add2(u,v);
}
l=0,r=1;f[1]=n;
while (l++<r)
{
for (int p=head[f[l]],v;p;p=g[p].fr)
if (!bz[v=g[p].v]) bz[v=g[p].v]=2,f[++r]=v;
}
l=0,r=1;f[1]=1;
while (l++<r)
{
for (int p=tail[f[l]],v;p;p=e[p].fr)
if (bz[v=e[p].v]--) d[v]=min(d[v],d[f[l]]),f[++r]=v;
}
for (int i=1;i<=n;i++) ans=max(ans,a[i]-d[i]);
printf("%d
",ans);
return 0;
}