contents:

  • 写在前面
  • 拓扑排序
    • 代码
    • 对应题目
    • AC代码
  • 最短/长路
    • 无权最短路
    • 无权最长路
    • 带权最短路
    • 带权最长路
    • spfa
    • 优先对列优化dijkstra
      • BELLMAN_FORD
    • FLOYD_WARSHALL 多源点最短路径

写在前面

以下图均有向无环图

拓扑排序

按照自己想的去暴力即可

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 1E5 + 10;
vector<int> g[N]; //邻接表
int deg[N];       //每个节点的入度
int u, v;
vector<int> ans; //记录结果int main()
{int n; //顶点个数[0,n-1]int e; //边的个数cin >> n >> e;for (int i = 1; i <= e; i++){cin >> u >> v;     //u-->vg[u].push_back(v); //记录有向边deg[v]++;          //v点入度加一}queue<int> q; //记录入度为0的节点队列for (int i = 0; i < n; i++){if (deg[i] == 0)q.push(i); //将不需要操作入度为0的记录下来}while (!q.empty()){int x = q.front();ans.push_back(x); //记录拓扑顺序q.pop();int sz = g[x].size();for (int i = 0; i < sz; i++){deg[g[x][i]]--;if (deg[g[x][i]] == 0)q.push(g[x][i]);}}int nn = ans.size();if (nn == n){for (int i = 0; i < n; i++){cout << ans[i] << " ";}cout << endl;}else{cout << "no found" << endl;}system("pause");return 0;
}

对应题目

链接: link.

AC代码

#include <bits/stdc++.h>
using namespace std;
const int N = 1E5 + 10;
vector<int> g[N]; //邻接表
int deg[N];       //每个节点的入度
int u, v;
vector<int> ans; //记录结果int main()
{int n; //顶点个数[0,n-1]int e; //边的个数cin >> n >> e;for (int i = 1; i <= e; i++){cin >> u >> v;     //u-->vg[u].push_back(v); //记录有向边deg[v]++;          //v点入度加一}queue<int> q; //记录入度为0的节点队列for (int i = 1; i <= n; i++){if (deg[i] == 0)q.push(i); //将不需要操作入度为0的记录下来}while (!q.empty()){int x = q.front();ans.push_back(x); //记录拓扑顺序q.pop();int sz = g[x].size();for (int i = 0; i < sz; i++){deg[g[x][i]]--;if (deg[g[x][i]] == 0)q.push(g[x][i]);}}int nn = ans.size();if (nn == n){for (int i = 0; i < n; i++){cout << ans[i] << " ";}cout << endl;}else{cout << -1 << endl;}system("pause");return 0;
}

模板自己总结最好

最短/长路

比较懒,各个边的数值大家假装先看不见

无权最短路

#include <bits/stdc++.h>
using namespace std;
const int N = 1E5 + 10;
vector<int> g[N];
int deg[N];
int u, v;
int dis[N];
#define INF 0x3f3f3f3fint main()
{int n, e, st, ed;cin >> n >> e >> st >> ed;for (int i = 1; i <= e; i++){cin >> u >> v;     //u-->vg[u].push_back(v); //记录有向边deg[v]++;          //v点入度加一}memset(dis, INF, sizeof(dis));dis[st] = 0;queue<int> q; //记录入度为0的节点队列for (int i = 0; i < n; i++){if (deg[i] == 0)q.push(i); //将不需要操作入度为0的记录下来}while (!q.empty()){int x = q.front();q.pop();int from = dis[x];int sz = g[x].size();for (int i = 0; i < sz; i++){deg[g[x][i]]--;dis[g[x][i]] = min(dis[g[x][i]], from + 1);if (deg[g[x][i]] == 0)q.push(g[x][i]);}}cout << dis[ed] << endl;system("pause");return 0;
}

无权最长路

在无权最短路修改两个地方即可

21行
memset(dis, 0, sizeof(dis));
39行
dis[g[x][i]] = max(dis[g[x][i]], from + 1);
output
4

带权最短路

无非就是多个权值呗(其实是将默认权值1改成具体了)
图见上图

#include <bits/stdc++.h>
using namespace std;
#define pii pair<int, int>
const int N = 1E5 + 10;
vector<pii> g[N];
int deg[N];
int u, v, w; //u-->,权值为w
int dis[N];
#define INF 0x3f3f3f3fint main()
{int n, e, st, ed;cin >> n >> e >> st >> ed;for (int i = 1; i <= e; i++){cin >> u >> v >> w;              //u-->vg[u].push_back(make_pair(v, w)); //记录有向边deg[v]++;                        //v点入度加一}memset(dis, INF, sizeof(dis));dis[st] = 0;queue<int> q; //记录入度为0的节点队列for (int i = 0; i < n; i++){if (deg[i] == 0)q.push(i); //将不需要操作入度为0的记录下来}while (!q.empty()){int x = q.front();q.pop();int from = dis[x];int sz = g[x].size();for (int i = 0; i < sz; i++){deg[g[x][i].first]--;dis[g[x][i].first] = min(dis[g[x][i].first], from + g[x][i].second);if (deg[g[x][i].first] == 0)q.push(g[x][i].first);}}cout << dis[ed] << endl;system("pause");return 0;
}
input
6 6
2 5
4 5 2
3 4 1
1 4 3
1 3 1
2 1 1
0 1 1
output
5

带权最长路

你还要往这看?

spfa

#include <bits/stdc++.h>
using namespace std;
#define pii pair<int, int>
const int N = 1E5 + 10;
vector<pii> g[N];
int u, v, w; //u-->,权值为w
int dis[N];  //距离
int vis[N];
#define INF 0x3f3f3f3fint main()
{int n, e, st, ed;cin >> n >> e >> st >> ed;for (int i = 1; i <= e; i++){cin >> u >> v >> w;              //u<-->vg[u].push_back(make_pair(v, w)); //记录有向边g[v].push_back(make_pair(u, w)); //记录有向边}memset(dis, INF, sizeof(dis));dis[st] = 0;queue<int> q;q.push(st);vis[st] = 1;while (!q.empty()){int x = q.front();q.pop();vis[x] = 0; //出队int from = dis[x];int sz = g[x].size();for (int i = 0; i < sz; i++){dis[g[x][i].first] = min(dis[g[x][i].first], from + g[x][i].second);if (dis[g[x][i].first] == from + g[x][i].second) //更新过了{if (vis[g[x][i].first] == 0){q.push(g[x][i].first);vis[g[x][i].first] = 1;}}}}cout << dis[ed] << endl;system("pause");return 0;
}
input
10 14 1 10
1 3 1
3 4 1
4 2 1
1 2 4
2 5 1
2 6 1
2 7 1
2 8 1
2 9 1
10 5 1
10 6 1
10 7 1
10 8 1
10 9 1
output
5

有负环不存在最短路,不断重复环就能够将某些点值刷低
有负边无负环仍然有最短路

链接: link.
链接: link.
链接: link.
链接: link.
链接: link.

复杂度是O(n*e)的
阐释优化

优先对列优化dijkstra

原因:只入队一次,当再次入队那比没有之前更优

#include <bits/stdc++.h>
using namespace std;
const int N = 1E5 + 10;
#define pii pair<int, int>
#define mp make_pair
#define INF 0x3f3f3f3f
vector<pii> g[N]; //uvw
int u, v, w;
int n, e, st, ed;
int dis[N];
int vis[N];
#define gp greater<pii>
priority_queue<pii, vector<pii>, gp> q;//dis,id
void dijk()
{q.push(mp(0, st));dis[st] = 0;while (!q.empty()){int now = q.top().second;q.pop();if (vis[now]){continue;}vis[now] = 1;int sz = g[now].size();for (int i = 0; i < sz; i++){int v = g[now][i].first;int w = g[now][i].second;if (dis[now] + w < dis[v]){dis[v] = dis[now] + w;q.push(mp(dis[v], v));}}}return;
}int main()
{cin >> n >> e >> st >> ed;memset(dis, INF, sizeof(dis));for (int i = 1; i <= e; i++){cin >> u >> v >> w;g[u].push_back(mp(v, w));g[v].push_back(mp(u, w));}dijk();cout << dis[ed] << endl;system("pause");
}
input
10 14 1 10
1 3 1
3 4 1
4 2 1
1 2 4
2 5 1
2 6 1
2 7 1
2 8 1
2 9 1
10 5 1
10 6 1
10 7 1
10 8 1
10 9 1
output
5

BELLMAN_FORD

就是未更新的spfa
遍历所有的边,更新所有的边,如果有边变得更短就继续,如果没有就停止更新(非常非常暴力的想法)

FLOYD_WARSHALL 多源点最短路径

#include <bits/stdc++.h>
using namespace std;
const int N = 1E3 + 10;
#define INF 0x3f3f3f3f
int g[N][N], n, e;
int main()
{cin >> n >> e;int u, v, w;memset(g, INF, sizeof(g));for (int i = 0; i < e; i++){cin >> u >> v >> w;g[u][v] = g[v][u] = min(g[v][u], w); //重边}for (int i = 1; i <= n; i++){g[i][i] = 0;}for (int k = 1; k <= n; k++){for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){g[i][j] = min(g[i][j], g[i][k] + g[k][j]);}}}for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){cout << g[i][j] << " ";}cout << endl;}system("pause");return 0;
}



yp北京理工 拓扑排序+最短路(更新中re)相关推荐

  1. 拓扑排序在实际项目中应用

    前言: 在实际工作场景中用到了拓扑排序,遂记录下来以供参考理解. 拓扑排序介绍: 首先,拓扑排序区别于一般的数值类排序算法,如冒泡排序.快速排序.堆排序等.它的处理对象是有向无环图DAG,最终是把有向 ...

  2. 0x21.搜索 - 树与图的遍历、拓扑排序

    目录 一.树与图的深度优先遍历及树的一些性质 1.树与图的深度优先遍历 2.时间戳 3.树的DFS序(树链剖分前驱知识) 4.树的深度 5.树的重心与sizesizesize 6.图的连通块划分 二. ...

  3. python 拓扑排序 dfs bfs_拓扑排序的DFS和BFS

    博主以前有一个疑问,DFS和BFS各自的适用范围是?我想你今天看了这篇文章之后会有一个判断! BFS 数据结构与算法分析:c语言描述(p217) 已经存在一个Indgree入度数组(indgree[v ...

  4. 数据结构(六):图的概念、存储方式、基本操作、最小生成树、最短路径、有向无环图、关键路径 | Prim、Kruskal算法 | BFS、Dijkstra、Floyd算法 | 拓扑排序 | 求关键路径

    文章目录 第六章 图 一.图 (一)图的定义 (二)图逻辑结构的应用 (三)无向图.有向图 (四)简单图.多重图 (五)顶点的度.入度.出度 (六)顶点-顶点的关系描述 (七)连通图.强连通图 (八) ...

  5. 2192. 有向无环图中一个节点的所有祖先(邻接表 加 拓扑排序)

    如果直接使用邻接表不记录已经遍历过的数,暴力搜索超超时,所以需要拓扑排序来记录入度为0的点,入度为0时,他之前的父节点已经记录完毕,可以直接加入到他的子节点中. 最后还需要转换结果,从小到大,直接用s ...

  6. 拓扑排序之java实现_有向图和拓扑排序Java实现

    package practice; import java.util.ArrayDeque; import java.util.Iterator; import java.util.Stack; pu ...

  7. 数据结构C++——拓扑排序

    数据结构C++--拓扑排序 文章目录 数据结构C++--拓扑排序 一.前言 二.拓扑排序的概念及作用 三.拓扑排序的实现 ①拓扑排序的实现原理 ②拓扑排序中FindInDegree()函数的实现 ③拓 ...

  8. C/C++二级指针概念及应用(有向图的邻接表(拓扑排序)、有向网图的邻接表、树的孩子表示)

    目录 一.概述 例1: 例2: 代码: 二.实例 1.有向图的邻接表(拓扑排序) 2.有向网图的邻接表 3.树的孩子表示 一.概述 二级指针:指向指针的指针.一般需要修改地址的时候会用到二级指针. 注 ...

  9. 【zz】如何去理解 拓扑排序算法

    from http://www.cnblogs.com/shanyou/archive/2006/11/16/562861.html 查看Castle的代码,在Castle.Core中内部的数据结构采 ...

最新文章

  1. 独家 | 层级聚类和Python实现的初学者指南(附链接)
  2. oracle11g导出空表
  3. 语句 if else
  4. c#编程实战宝典 付强_C#开发实战宝典pdf
  5. 推荐工具 HBuilder
  6. OSPF多区域配置【eNSP实现】
  7. 计算机网络拓扑结构的分析,计算机网络拓扑结构分析
  8. 学拳录 23退步压肘
  9. MySQL查看表结构SQL语句
  10. 《花开半夏》--4 生死之间的吻(1)
  11. STM32F103-LED模块
  12. 夜光带你走进python开发 (三十九)传奇语言
  13. BTC交易标准分类(对比说明)
  14. ㉕AW-A33 Linux驱动开发之audio子系统驱动程序
  15. opensuse的快捷键
  16. 服务器开关电源型号ab和sb,SB21150AB 开关电源的PWM调整电流上升率
  17. 链路汇聚 Eth-trunk
  18. opencv常用函数整理
  19. 什么是wifi霸屏神器?用WiFi霸屏广告机打广告是什么体验?
  20. Google Play约会游戏开发者,ChinaJoy 2017完美收官!

热门文章

  1. Cocos Creator 优化,帧动画优化
  2. 程序员买房前后对比,看完后已哭瞎...
  3. 什么是JRE?Java运行环境简介
  4. uniapp设置导航栏、沉浸式导航栏以及获取屏幕尺寸
  5. 解决git拉取代码时报:Auto packing the repository in background for optimum performance
  6. 《敦煌》—— 读后总结
  7. 任务七、名片管理系统
  8. Kali-Linux安装驱动并使用Blueman连接蓝牙耳机
  9. 基于matlab在信号与系统仿真中的应用,基于MATLAB在信号与系统仿真中的应用
  10. 利用Python获取最新的sci论文摘要信息并群发邮箱