首页 > 其他分享 >最短路

最短路

时间:2023-03-25 20:33:07浏览次数:30  
标签:dist int 短路 更新 st edge

一.Bellman-Ford

主要适用场景:
1.这主要是一个用来判断是否存在负环的
2.当边权可为负数时Dijkstra算法不成立!这个可以很容易去判断!!!
所以此时只能去弄 Bellman-Ford !!
Bellman-Ford
用 dist[i] 去记录所有节点的最短路径!!
理解:首先确定一个目标顶点然后把其距离赋值为0,然后把其他赋值为无穷大然后不断用边去更新所有的节点看看最短路是否能被更新,一开始能被更新的一定是起点所连出去的然后不断拓展出去,但是边更新时是一条条边枚举过去更新的,故可能最后才能被更新到,且每次更新时可能只更新到一个点,(边的编号在最后,要跑到最后才被更新,而前面又不能更新,所以最差去看下只能更新一个点,此时复杂度O(NM)!!)而且因为这个原因只要有点能被更新,操作就得继续,可能被更新的点连出去的边还能更新其他的点!!没被更新的点不可能更新其他点(确信!!
这就是算法的核心吧,不断去更新点!!这样代码便容易写出!!

struct edge{
	int x,y,z;
}edge[M+1];
int n,m,dist[N+1],pre[N+1];
int bfs(int s,int t)
{
  memset(dist,127,sizeof(dist));
  memset(pre,0,sizeof(pre));
  dist[s]=0;
  while(1)
    {
	bool ok=false;
	for(int i=1;i<=m;i++)//最差迭代 n-1 次每次只能枚举到一条有效的边 
	{
   int x=edge[i].x,y=edge[i].y,v=edge[i].z;  //每一次迭代去看所有边是否能被更新!!!
	  if(dist[x]<1<<30)
	     {
	      if(dist[x]+v<dist[y])
		{
		dist[y]=dist[x]+v;
		pre[y]=x;//记录一个状态数组从哪里来的
		ok=true;  // 能被更新才有下一次更新!!
		}
	      }
	}
	if(!ok)
	break;
    }
	return dist(t);
}

当然还有一个队列优化(spfa 但是不推荐用因为很容易被卡不如跑一个Dijkstra
这样更新边也快好像不要跑一个 o(nm) 了跑边只需跑一些
那就便可完全摒弃bellman——ford直接跑一个spfa
不过当边权出现负值时

void spfa(int s,int t)
{
	memset(dist,127,sizeof(dist));
	memset(st,0,sizeof(st));
	dist[s]=0;
	int front=1,rear=1;
	q[rear]=s;
	st[s]=true;  //现在在队列里面
	while(front<=rear)
	{
		int x=q[front++];  //出队现在不在队列里面
		st[x]=false;       // 队列x可重新入队!!
		for(auto i:edge[x])
		{
			if(dist[i.first]>dist[x]+i.second)
			{
			dist[i.first]=dist[x]+i.second;
			if(!st[i.first])
			{
				q[++rear]=i.first;
				st[i.first]=true;
			}
			}
		}
	}
	if(dist[t]<1<<30) cout<<dist[t]<<'\n';
	else cout<<-1<<'\n';
}

找一个点到多个点最短路的和 ,可以去从终点开始找每个点的最短路,然后去看哪个点加起来最小!!

这道题就是一个典型题目逆向的一个思维!!

#include <bits/stdc++.h>
using namespace std;
int n,m,k,d[20001];
vector<pair<int,int>> edge[20001];
vector<int> q[20001];
int main()
{
	cin>>n>>m>>k;
	int i;
	for(i=1;i<=m;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
		edge[x].push_back({y,z});
		edge[y].push_back({x,z});	
	}
	while(k--)
	{
		int fx,fy;
		cin>>fx>>fy;
		for(i=0;i<=n;i++)
		q[i].clear();
		memset(d,255,sizeof(d));
		d[fx]=0;
		q[0].push_back(fx);
		for(i=0;!q[i].empty();i++)
		{   //这样去写队列的原因 :vector 从0开始存东西的!!
			int front=0,rear=q[i].size()-1;   //先把所有起始点为0的加入进入队列中
			while(front<=rear)
			{
				int x=q[i][front++];
				for(auto y: edge[x])
				{
					if(!y.second&&d[y.first]==-1)
					{
						d[y.first]=d[x];
						q[i].push_back(y.first); //距离在同一层存在同一个q[i]中!!
						rear++;
					}
				}
			}
			if(d[fy]!=-1) break;
			for(int j=0;j<=rear;j++)//细节并不是从front 开始而是从头到尾全部重新走一遍!!
			{
				int x=q[i][j];
				for(auto y:edge[x])
				{
					if(y.second&&d[y.first]==-1)
					{
						d[y.first]=d[x]+1;
						q[i+1].push_back(y.first);//距离加1了在下一层
					}
				}
			}
		}
		printf("%d\n",d[fy]);
	}
}

标签:dist,int,短路,更新,st,edge
From: https://www.cnblogs.com/--Lance/p/17255355.html

相关文章

  • 使用SQL语句实现最短路线问题
    今天学习了一种直接用sql语句实现查询最短路径的方法,为我们的系统开发提供了便利。Stringsql="WITHRECURSIVEtransfer(start_station,stop_station,stops,path)......
  • 逻辑运算符短路特性
    &&短路特性遇到假即为假,不会判断下一组表达式||短路特性遇到真即为真,不会判断下一组表达式......
  • 「最短路径树」黑暗城堡
    本题为3月17日23上半学期集训每日一题中B题的题解题面题目描述在顺利攻破Lordlsp的防线之后,lqr一行人来到了Lordlsp的城堡下方。Lordlsp黑化之后虽然拥有了......
  • 多源最短路Floyd本质理解
    \(Floyd\)总结复习Floyd是动态规划的典型体现,其思想从集合角度用闫氏DP分析法即可其关键的性质理解:即外层循环k的理解。\(dist[k][i][j]\)代表(k的取值范围是从1到n),在考......
  • 简单图最短路径
    graph={'保安':['巡检','巡逻','监控'],'监控':['监视','密切','白领'],'巡逻':['白领','蓝领','科学家'],'白领':['销售','大堂经理',&#......
  • 多源最短路算法——Floyd算法(转载)
    1.多源最短路简介:我们知道单源最短路是指从某一个源点到图中的其它顶点的最短路。多源最短路就是指每一个点到图中其他顶点的最短路。那么有的人肯定想我知道求单源最短路......
  • 最短路
    #include<bits/stdc++.h>usingnamespacestd;intg[205][205];intmain(){memset(g,0x3f,sizeofg);intn,m,k;cin>>n>>m>>k;while(m--){in......
  • 最短路计数
    /*边权值都为1,所以可以用BFS来做记住BFS和dikstra都是满足拓扑序性质的,也就是说可以用二者解决图论中的dp问题,而spfa不满足拓扑序的性质*/#include<bits/st......
  • AcWing 第 94 场周赛 A B(最短路dij) C(最短路floyed)
    https://www.acwing.com/activity/content/competition/problem_list/2961/AcWing4870.装物品水题#include<bits/stdc++.h>usingnamespacestd;typedeflonglon......
  • 最短路之和
    最短路之和给定一个$n$个点的加权有向图,点的编号为$1\simn$。图中任意两点之间都有两条方向相反的边连接两点。从点$i$到点$j$的边的长度为$a_{ij}$。给定一......