其他分享
首页 > 其他分享> > 最优贸易

最优贸易

作者:互联网

求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