标签:int 最大值 spfa vis 最小值 贸易 最优 id
求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;
}
对于图上的先后顺序 可以考虑能不能用最短路来解决
标签:int,最大值,spfa,vis,最小值,贸易,最优,id 来源: https://www.cnblogs.com/juruoHBr/p/15755965.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。