在图论里,最短路,次短路,k短路的问题很常见。
这里总结一下。

存图技巧

数据小,稠密图的一般用邻接矩阵
稀疏图,数据大一般用邻接表(vector,链式前向星都可)

邻接矩阵

const int maxn = 1e5+5;
int Graph[maxn][maxn];  // 正权图可以初始化成-1来判断是否连通,负权图可以再考虑开个数组或者用一个很大的值。

链式前向星

const int maxn = 1e5+5;
struct Edge{int u,v,nxt;
}edge[maxn];
int head[maxn],tot;
inline void addedge(int u,int v,int w){ // u->v 权值是wedge[++tot] = {u,v,w};head[u] = tot;
}

最短路

一般最短路算法有 BFS(暴力,一般只适用于点数小的情况),dijiastra(解决正权图),spfa(解决负权图,但容易死,被卡),floyed(解决点与点之间的最短距离问题,dp)

这里直接给出单源最短路的算法(因为都挺好理解的) (重点在于松弛操作!)

dijiastra

// 堆优化版本
const int maxn = 1e5+5;
struct Edge{int u,v,nxt,w;
}edge[maxn];
int head[maxn],tot;
inline void init(){memset(head,-1,sizeof(head));
}
inline void addedge(int u,int v,int w){edge[++tot] = {u,v,head[u],w};head[u] = tot;
}
int dis[maxn];  bool vis[maxn];
inline void dijiastra(int s){struct Node{int u,dis;bool operator <(const Node &h)const{return dis > h.dis;}};memset(dis,0x3f,sizeof(dis));   //  视具体情况而定初始化的值dis[s] = 0;priority_queue<Node> pq;    pq.push(Node{s,0});while(!pq.empty()){Node u = pq.top();  pq.pop();if(vis[u.u])    continue;vis[u.u] = true;for(int i = head[u.u]; ~i; i = edge[i].nxt){Edge &e = edge[i];if(dis[e.v] > u.dis + e.w){dis[e.v] = u.dis + e.w;pq.push(Node{e.v,dis[e.v]});}}}
}

spfa

struct Edge{int v,d;Edge(int vv,int dd):v(vv),d(dd){}
};
struct Node{int u,cost;Node(int uu,int cc):u(uu),cost(cc){}bool operator < (const Node & h)const{return cost > h.cost;}
};
const int MAX = 1e5+5;
vector < Edge > edges;
vector < int > Graph[MAX];
bool vis[MAX];
int dp[MAX];
void AddEdge(int u,int v,int dis){edges.push_back(Edge{v,dis});Graph[u].push_back(edges.size()-1);
}
void SPFA(int s,int n){memset(dp,0x3f,sizeof(dp));dp[s-1] = 0;priority_queue<Node>q ;q.push(Node{s-1,0});  vis[s-1] = 1;while(!q.empty()){Node x = q.top(); q.pop();int u = x.u; vis[u] = 0; // cancel the tag;for(int i = 0; i < Graph[u].size(); ++i ){Edge & e = edges[Graph[u][i]];if( dp[e.v] > dp[u]+ e.d ){dp[e.v] = dp[u] + e.d;if(!vis[e.v]) q.push(Node{e.v,dp[e.v]});vis[e.v] = 1;}}}
}

次短路(利用最短路来求)

目前见到的方法一般有两种,遍历or删边

1.删边。
首先使用最短路算法求出s−ts - ts−t的最短路,并且记录下最短路的路径(在松弛的时候记录前驱),然后对于这条路径,我们依次去删去一条边,然后跑最短路,去更新ans

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
const double inf = 1e9+5;
struct Edge{int u,v,nxt;    double w;
}edge[maxn];
int head[maxn],tot;
pair<int,int> path[maxn];
inline void addedge(int u,int v,double w){edge[++tot] = {u,v,head[u],w};head[u] = tot;
}
inline void init(){memset(head,-1,sizeof(head));tot = 0;
}double dis[maxn];   bool vis[maxn];
bool isok[maxn];
inline void dijiastra(int s){struct Node{int u;  double dis;bool operator <(const Node &h)const{return dis > h.dis;}};for(int i = 0; i < maxn; ++i)  dis[i] = inf,vis[i] = false;priority_queue<Node> pq;    pq.push(Node{s,0});while(!pq.empty()){Node u = pq.top();  pq.pop();if(vis[u.u])continue;vis[u.u] = true;for(int i = head[u.u]; ~i; i = edge[i].nxt){if(isok[i]) continue;Edge &e = edge[i];if(dis[e.v] > u.dis + e.w){ //  松弛过程中记录dis[e.v] = u.dis + e.w;path[e.v] = make_pair(u.u,i);pq.push(Node{e.v,dis[e.v]});}}}
}
struct Point{int x,y;
}p[maxn];
inline double get_dis(const Point &p,const Point&q){return sqrt( (p.x-q.x)*(p.x-q.x) + (p.y-q.y)*(p.y-q.y));
}
int main()
{ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);init();int n,m;    cin >> n >> m;for(int i = 1; i <= n; ++i) cin >> p[i].x >> p[i].y;for(int i = 0,u,v; i < m; ++i){cin >> u >> v;  double d = get_dis(p[u],p[v]);addedge(u,v,d); addedge(v,u,d);}dijiastra(1);pair<int,int> tt = path[n];vector<int> ee; ee.push_back(tt.second);while(tt.first!=1){tt = path[tt.first];ee.push_back(tt.second);}double ans = inf;for(int i = 0; i < ee.size(); ++i){isok[ee[i]] = true;dijiastra(1);isok[ee[i]] = false;ans = min(ans,dis[n]);}if(ans==inf){cout << -1 << endl;}else cout <<fixed<<setprecision(2)<< ans << endl;return 0;
}

2.遍历。
跑两次最短路,分别是以起点,以终点。 然后遍历所有边,去更新长度
∑e(u,v)∈G(v,e)min(dis[1][u]+w(u,v)+dis[v][n])\sum_{e(u,v)\in G(v,e)}min(dis[1][u]+w(u,v)+dis[v][n])∑e(u,v)∈G(v,e)​min(dis[1][u]+w(u,v)+dis[v][n])

k短路 ( A*或者左偏树)(当然也可以用于解决次短路问题)

左偏树,A*待更新

左偏树学习:大佬博客

【图论算法】 最短路,次短路,k短路总结相关推荐

  1. NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先

    系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...

  2. 综合算法05—考虑换乘的K短路算法

    一.问题描述 在路网中,已知站点.线路和线路-站点数据,有条件: 1.考虑到换乘时要花费一定的时间,因此对换乘路径费用要加上换乘时间. 2.当路网复杂时,为了避免多余计算,定义有效路径,使得路径在有效 ...

  3. 第K短路+严格第K短路

    所谓K短路,就是从s到t的第K短的路,第1短就是最短路. 如何求第K短呢?有一种简单的方法是广度优先搜索,记录t出队列的次数,当t第k次出队列时,就是第k短路了.但点数过大时,入队列的节点过多,时间和 ...

  4. A*算法+最短路实现K短路+模板题

    <font color=black size=4>K短路问题还是很普遍的,了解一下K短路很有必要,顺便学会A*的简单应用更好. A*算法,是一种启发式搜索算法,我们可以自己设定一个估价函数 ...

  5. 次短路(两种方式) 第K短路

    次短路算法: 有两种比较简单实现次短路的思想 方法一:用 dijkstra 算法 从起点开始 同时维护 [最短路数组(dis1[ ])] 和 [次短路 数组 (dis2[ ])] 方法二:还是用到di ...

  6. poj2449(k短路算法)

    K 短路问题(A* 启发式广搜) 1.k 短路问题就是最短路问题的延申,要找出第 k 短的路径.用广搜进行路径查找,第一次找到的 就是最短路,第二次找到的是第 2 短 路⋯以此类推.所以我们只需要一直 ...

  7. A*算法的认识与求第K短路模板

    现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...

  8. 第k短路 (A*算法)

    A*算法: A*,启发式搜索,是一种较为有效的搜索方法. 我们在搜索的时候,很多时候在当前状态,已经不是最优解了,但是我们却继续求解:这个就是暴力搜索浪费时间的原因. 我们在有些时候,往往可以根据一些 ...

  9. ACM-ICPC 2018 沈阳赛区网络预赛 D Made In Heaven(第k短路,A*算法)

    https://nanti.jisuanke.com/t/31445 题意 能否在t时间内把第k短路走完. 分析 A*算法板子. #include <iostream> #include ...

最新文章

  1. android 弹幕时间戳,【存档】B站直播数据包分析连载(2018-12-11更新/2020-04-12废止)...
  2. EST:西湖大学鞠峰组-污水厂病原菌与土著反硝化细菌是多重抗生素耐药基因的活跃表达者...
  3. linux中cat more less head tail 命令区别
  4. Oracle 存储过程异常处理
  5. Mysql Too many connections解决方法
  6. Androidstudio坑
  7. #python练习实例0:制作1-100随机抽取3个数字排队列
  8. Google 5.5亿美金投资了京东?
  9. 互信息python代码_转:标准化互信息NMI计算步骤及其Python实现
  10. liunx安装jdk,实测有效
  11. linux维文字体如何下载,uyghurfont
  12. 外接圆、内切圆半径公式及相应关系知识点总结
  13. 最详细教程:Zotero和Better BibTeX安装,以及如何在R markdown中引用文献
  14. 【R语言】ggplot2:初次见面,请多多关照!
  15. (附源码)springboot跨境电商系统 毕业设计 211003
  16. 中学生应具备的良好的学习习惯
  17. 小小英雄怎么修改服务器,英雄联盟自走棋小小英雄怎么换 LOL英雄战棋小小英雄皮肤更改方法...
  18. 虚拟现实在多领域的解决方案
  19. osChina.net工具
  20. 花朝节汉服摄影征集、照片征集、视频征集小程序

热门文章

  1. IDEF1X建模方法
  2. 你真的理解持续集成(CI)吗?
  3. ios wkwebview弹框_iOS 加载WKWebView
  4. 2.6 RMSprop
  5. 计算机科学与技术 网瘾,曾经电击治疗网瘾的杨永信,受无数家长追捧,现在如何了?...
  6. 关于函数(二)数组指针和指针数组
  7. STM32定时器总结
  8. 关于人的发展的理性思考与误区分析
  9. 计算机视觉课程第五讲-带你简单快速学习2021年春晚背后刘德华与背景分离切换到另一场景视觉算法...
  10. JSP include参数的中文乱码问题