首页 > 其他分享 >Johnson 全源最短路

Johnson 全源最短路

时间:2023-05-24 20:24:58浏览次数:46  
标签:node Johnson int 全源 3005 SPFA include 短路

全源最短路,换一种说法就是n个单源最短路,可以用n次Bellman-Ford或SPFA,非负边权还可以用Dijkstra,可是有负边权用前两个算法还是慢,如果我们能把负边权映射成非负边权的话,一切就都好办了

这里我们引入一个虚拟结点,它和所有点的初始距离都是0,然后,我们求出来这个结点和其他店的最短路h,然后,我们将各个边边权变为w+h[u]-h[v](如果最短路不经过u,也就是不满足松弛操作h[v]>h[u]+w,如果经过u,h[v]=h[u]+w,所以一定非负)

然后,我们就可以用n次Heap-Dijkstra来求了

时间复杂度O(nm+n(mlogn))(SPFA+n*Heap-Dijkstra)
与floyed相比,此算法适合用在稀疏图

例题 洛谷 P5905 【模板】Johnson 全源最短路

#include<iostream>
#include<vector>
#include<queue>
#include<utility>
#include<cstring>
#define forup(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long ll;
const ll INF=1e9;
struct edge{ int v,w; };
vector<edge> node[3005];
int d[3005];
int n,m;

int h[3005];
queue<int> q;
bool ex[3005];
int cnt[3005];//判负环用的,见SPFA算法 
int SPFA(int s)
{
	memset(h,127,sizeof(h));
	h[s]=0; q.push(s); ex[0]=true;
	while(!q.empty())
	{
		int u=q.front();
		for(auto x:node[u])
		{
			int v=x.v,w=x.w;
			if(h[u]+w<h[v])
			{
				h[v]=h[u]+w;
				if(!ex[v]) {
					q.push(v); ex[v]=true;
					cnt[v]=cnt[u]+1;
					if(cnt[v]>n) return -1;
				}
			}
		}
		q.pop(); ex[u]=false;
	}
	return 0;
}
void dijkstra(int s)
{
	priority_queue<pair<int,int>> q;
	bool vis[3005]={};
	forup(i,1,n) d[i]=INF;
	d[s]=0;
	q.push({0,s});
	while(!q.empty())
	{
		int u=q.top().second; q.pop();
		if(vis[u]) continue;
		else vis[u]=true;
		for(auto x:node[u])
		{
			int v=x.v,w=x.w;
			if(d[u]+w<d[v]) d[v]=d[u]+w;
			q.push({-d[v],v});
		}
	}
}
int main()
{
	cin>>n>>m;
	int u,v,w;
	forup(i,1,m)
	{
		cin>>u>>v>>w;
		node[u].push_back({v,w});
	}
	forup(i,1,n) node[0].push_back({i,0});
	if(SPFA(0)==-1){//判负环的 
		cout<<-1;
		return 0;
	}
	forup(u,1,n)
	{
		for(auto &x:node[u])
		{
			x.w+=h[u]-h[x.v];//映射 
		}
	}
	forup(u,1,n)
	{
		dijkstra(u);
		ll ans=0;
		forup(v,1,n) 
			if(d[v]==INF) ans+=INF*v;
			else ans+=(ll)(d[v]-h[u]+h[v])*v;
		cout<<ans<<'\n';
	}
	return 0;
}

参考:https://www.cnblogs.com/dx123/p/16320444.html

标签:node,Johnson,int,全源,3005,SPFA,include,短路
From: https://www.cnblogs.com/V-sama/p/17429389.html

相关文章

  • Floyed 全源最短路
    全源最短路,顾名思义,就是任意两点之间的最短路floyed的思路就是每次选一个点k,如果k不在u和v路径上,就不改变,如果k在u和v的路径上,进行松弛操作d[u][v]=min(d[u][v],d[u][k]+d[k][v])例题洛谷B3647【模板】Floyd算法#include<iostream>#defineforup(i,l,r)for(inti=l;i<=r;......
  • 浅谈 树上带权最长最短路径,决策包容性与点分树
    树上带权最长最短路径,决策包容性与点分树\(\text{preface}\)最近学习了点分树相关的内容,也碰巧见识到了许多……树上路径问题(非负权),最长或是最短,有的可以用点分治(树)解决,有的可以用线段树解决,有的需要深层次挖掘性质,就在这里做一个小小地总结了一些另类的方法。1.树上带权最长......
  • Bellman-Ford 单源最短路
    单源最短路,顾名思义,就是从一个起点到其余点的最短距离Bellman-Ford算法的思路是进行至多n-1轮的更新,每次遍历所有的边,进行松弛操作d[v]=min(d[v],d[u]+w);Bellman-Ford算法可以处理有负边权的图,也可以判负环,只要在第n轮还能进行松弛操作,说明存在负环例题洛谷P3371【模板】单......
  • LeetCode 周赛 346(2023/05/21)仅 68 人 AK 的最短路问题
    本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]提问。LeetCode单周赛第345场·体验一题多解的算法之美单周赛345概览T1.删除子串后的字符串最小长度(Easy)标签:栈T2.字典序最小回文串(Medium)标签:贪心、双指针T3.求一个整数的惩罚数(Medium)标签......
  • 最短路径算法
    最短路径问题这是一类最基本的图论问题,给定一个图,求从某一个源节点到某一个目的节点的最短路径。比较常见的算法有dijkstra,floyd,SPFA。在开始之前我们先说一说“松弛”这个词。在描述最短路径算法的时候,我们经常可以看到松弛(relaxtion)一词,通常来说,所有的最短路径算法都......
  • 【BZOJ2007】【NOI2010】海拔(对偶图,最短路)
    DescriptionYT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域。简单起见,可以将YT市看作一个正方形,每一个区域也可看作一个正方形。从而,YT城市中包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路(简称道路),每条双向道路连接主干道上两个相邻的交叉路口。下图为......
  • hdu:Arbitrage(最短路变形)
    ProblemDescriptionArbitrageistheuseofdiscrepanciesincurrencyexchangeratestotransformoneunitofacurrencyintomorethanoneunitofthesamecurrency.Forexample,supposethat1USDollarbuys0.5Britishpound,1Britishpoundbuys10.0......
  • hdu:六度分离(最短路)
    ProblemDescription1967年,美国著名的社会学家斯坦利·米尔格兰姆提出了一个名为“小世界现象(smallworldphenomenon)”的著名假说,大意是说,任何2个素不相识的人中间最多只隔着6个人,即只用6个人就可以将他们联系在一起,因此他的理论也被称为“六度分离”理论(sixdegreesofsepa......
  • ACM板子(1)(缺最短路、计算几何、数学、高级数据结构)
    ACM板子(1)(缺最短路、计算几何、数学、高级数据结构)快排、归并voidquicksort(int*num,intl,intr){if(r<=l)return;intx=l-1,y=r+1,z=num[l+r>>1];while(x<y){dox++;while(num[x]<z);doy--;while(num[y]>z);if(x<y)s......
  • hdu 1599 find the mincost route(无向图的最小环:求从一个点遍历所有节点以后回到原点
    题目:findthemincostrouteTimeLimit:1000/2000MS(Java/Others)    MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):2801    AcceptedSubmission(s):1115ProblemDescription杭州有N个景区,景区之间有一些双向的路来连接,现在8600想找一条旅游......