博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(写给自己看)最短路系列
阅读量:6871 次
发布时间:2019-06-26

本文共 3305 字,大约阅读时间需要 11 分钟。

(写给自己看)最短路系列

dijkstra算法

思想

  • 无负权的单源最短路
  • 每次扩展的是最短路径的点
  • priority_queue<node> 可轻松实现,同一节点可能有不同距离在队列中,但每次出优先队列都是最小的,也就是最短距离
#include 
#include
#include
#include
#include
#include
#include
using namespace std;//author:fridayfang//date:19 2月 27//global varibles#define ll long long;#define inf 0x3f3f3f3f#define CL(a,b) memset(a,b,sizeof(a))#define sf(a) scanf("%d",&a)#define pr(a) printf("%d\n",a)#define db(a) printf("db %d\n",a)#define fr0(i,m) for(int i=0;i
n2.di; }};int dij(int r){ CL(dis,0x3f); priority_queue
q; dis[r]=0,q.push(Node(r,dis[r])); int cntn=0; while(!q.empty()){ Node tmp=q.top(); q.pop(); int idx=tmp.idx; if(idx==b) return dis[idx]; for(int t=head[idx];t!=-1;t=es[t].nxt){ int v=es[t].v,w=es[t].w; if(dis[idx]+w

bellmanford

思想

  • 类似动态规划,求不超过\(0,1,2..(n-1)\)条边的最短路径
  • 每次枚举E条边\(<u,v>,dis[v]<dis[u]+w[u][v]\) 则更新dis[v]
  • 可判负环,\(n-1\)此后还能松弛则有负权环 O(E*V)
  • 优化算法 SPFA

    维护一个队列,里面存放所有需要进行迭代的点。初始时队列中只有一个

    源点S。用一个布尔数组记录每个点是否处在队列中。

每次迭代,取出队头的点v,依次枚举从v出发的边v->u, 若

Dist[v]+len(v->u) 小于Dist[u],则改进Dist[u](可同时将u前驱记为v)。
此时由于S到u的最短距离变小了,有可能u可以改进其它的点,所以若u不在
队列中,就将它放入队尾。这样一直迭代下去直到队列变空,也就是S到所
有节点的最短距离都确定下来,结束算法。 若一个点最短路被改进的次数达
到n ,则有负权环(原因同B-F算法) 。 可以用spfa算法判断图有无负权环

在平均情况下, SPFA算法的期望时间复杂度为O(E)

  • (这个好像是最长路,例题不太好)
#include 
#include
#include
#include
#include
#include
#include
using namespace std;//author:fridayfang//date:19 2月 27//global varibles#define ll long long;#define inf 0x3f3f3f3f#define CL(a,b) memset(a,b,sizeof(a))#define sf(a) scanf("%d",&a)#define pr(a) printf("%d\n",a)#define db(a) printf("db %d\n",a)#define fr0(i,m) for(int i=0;i
q;q.push(r); vis[r]=1;//表示进入队列 while(!q.empty()){ int tmp=q.front();q.pop(); vis[tmp]=0;//表示出队列 //printf("db %d dis: %d\n",tmp,dis[tmp]); for(int t=head[tmp];t!=-1;t=es[t].nxt){ //printf("db u->v %d->%d\n",tmp,es[t].v); int v=es[t].v,w=es[t].w; if(dis[tmp]+w>dis[v]){ dis[v]=dis[tmp]+w; if(vis[v]) continue; q.push(v);vis[v]=1; //if(ct[v]>=n) return -1;//表示有环 } } } return dis[d]; }int main(){ int t;sf(t); int minv=inf,maxv=0; CL(head,-1); int r=0; while(t--){ int x,y;sf(x),sf(y); add(x,y+1,2); r=max(y,r); } r++; for(int i=0;i
maxv?b:maxv; minv=a

floyd

思想

  • Floyd-Warshall算法的原理是动态规划。
  • 见即懂
  • 见也可
  • 也可解决传递闭包问题
#include 
#include
#include
#include
#include
#include
#include
using namespace std;//author:fridayfang//date:19 2月 27//global varibles#define ll long long;#define inf 0x3f3f3f3f#define CL(a,b) memset(a,b,sizeof(a))#define sf(a) scanf("%d",&a)#define pr(a) printf("%d\n",a)#define db(a) printf("db %d\n",a)#define fr0(i,m) for(int i=0;i
=inf||mp[k][j]>=inf) continue; if(mp[i][j]>mp[i][k]+mp[k][j]){ mp[i][j]=mp[i][k]+mp[k][j]; path[i][j]=k; } } } } /* fr1(i,n){ fr1(j,n){ printf("%d->%d: %d\n",i,j,mp[i][j]); } } */}int cowin[maxn];int main(){ while(~scanf("%d %d",&n,&m)){ CL(mp,0x3f); while(m--){ int t;sf(t); for(int j=1;j<=t;j++)sf(cowin[j]); fr1(i,t) fr1(j,t){ if(i!=j){ mp[cowin[i]][cowin[j]]=1; mp[cowin[j]][cowin[i]]=1; } } } floyd(); int ans=inf; fr1(i,n){ int tmp=0; fr1(j,n){ tmp+=mp[i][j]; } ans=min(ans,tmp); } //cout<

转载于:https://www.cnblogs.com/fridayfang/p/10519484.html

你可能感兴趣的文章
深入浅出Linux设备驱动编程--定时器
查看>>
常见移动设备的 CSS3 Media Query 整理(iPhone/iPad/Galaxy/HTC
查看>>
java递归-迷宫求解
查看>>
springboot加载顺序
查看>>
python chapter 学习之序列
查看>>
GlusterFS的基础应用
查看>>
ORA-09925: Unable to create audit trail file Linux-x86_64
查看>>
如何跳出嵌套语句之return
查看>>
API概述
查看>>
python2.6 安装rsa的包
查看>>
undo表空间使用率过高,且迟迟不释放问题
查看>>
scons *** no sconstruct file found求解决办法
查看>>
BIND基础配置详解
查看>>
火狐增加安全端口,每次用都得查,好麻烦,自己记录一下
查看>>
c# 多线程排队队列实现的源码
查看>>
LDA入门与Java实现
查看>>
19_css背景控制.html
查看>>
计算机网络测试和故障诊断的发展
查看>>
Delphi 与 DirectX 之 DelphiX(29): TDIB.AddMonoNoise();
查看>>
Windows Server 2008 FTP用户目录隔离模式
查看>>