求1-n上所有路径的点权最大值和最小值的差
方法一: spfa
很容易想到 从1开始跑一边和反图上n开始跑一边求交集就是正确的路径
但是这里还有一点是不能够返回 也就是对最大值和最小值出现有先后要求
这个时候把普通的bfs换成spfa就能够突出 "到"这一点
这里为什么不能用dij?
当前最小值还可能后面会出现更小的 当前最小值仍然有可能被更新 因此用spfa多次约束
方法二:
tarjan缩点后跑拓扑排序
void spfa(int s,int id)
{
while(q.size()) q.pop();
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++) d[i][id]=(id?-inf:inf);
d[s][id]=val[s]; vis[s]=1;
q.push( mp( id?val[s]:-val[s] ,s) );
while(q.size())
{
int x=q.front().second; q.pop();
vis[x]=0;
for(int i=head[x][id];i;i=e[i][id].next)
{
int y=e[i][id].to;
if(!id&&d[y][id]>d[x][id])
{
d[y][id]=min(d[x][id],val[y]);
if(!vis[y]) q.push( mp(-d[y][id],y) );
}
if( id&&d[y][id]<d[x][id])
{
d[y][id]=max(d[x][id],val[y]);
if(!vis[y]) q.push( mp(d[y][id],y) );
}
}
}
}
int main()
{
n=read(); m=read();
for(int i=1;i<=n;i++) val[i]=read();
for(int i=1;i<=m;i++)
{
int x=read(),y=read(),opt=read();
if(opt==1) _add(x,y,0),_add(y,x,1);
else add(x,y,0),add(y,x,1);
}
spfa(1,0); spfa(n,1);
int ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,d[i][1]-d[i][0]);
printf("%d",ans);
return 0;
}
对于图上的先后顺序 可以考虑能不能用最短路来解决