yp北京理工 拓扑排序+最短路(更新中re)
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)相关推荐
- 拓扑排序在实际项目中应用
前言: 在实际工作场景中用到了拓扑排序,遂记录下来以供参考理解. 拓扑排序介绍: 首先,拓扑排序区别于一般的数值类排序算法,如冒泡排序.快速排序.堆排序等.它的处理对象是有向无环图DAG,最终是把有向 ...
- 0x21.搜索 - 树与图的遍历、拓扑排序
目录 一.树与图的深度优先遍历及树的一些性质 1.树与图的深度优先遍历 2.时间戳 3.树的DFS序(树链剖分前驱知识) 4.树的深度 5.树的重心与sizesizesize 6.图的连通块划分 二. ...
- python 拓扑排序 dfs bfs_拓扑排序的DFS和BFS
博主以前有一个疑问,DFS和BFS各自的适用范围是?我想你今天看了这篇文章之后会有一个判断! BFS 数据结构与算法分析:c语言描述(p217) 已经存在一个Indgree入度数组(indgree[v ...
- 数据结构(六):图的概念、存储方式、基本操作、最小生成树、最短路径、有向无环图、关键路径 | Prim、Kruskal算法 | BFS、Dijkstra、Floyd算法 | 拓扑排序 | 求关键路径
文章目录 第六章 图 一.图 (一)图的定义 (二)图逻辑结构的应用 (三)无向图.有向图 (四)简单图.多重图 (五)顶点的度.入度.出度 (六)顶点-顶点的关系描述 (七)连通图.强连通图 (八) ...
- 2192. 有向无环图中一个节点的所有祖先(邻接表 加 拓扑排序)
如果直接使用邻接表不记录已经遍历过的数,暴力搜索超超时,所以需要拓扑排序来记录入度为0的点,入度为0时,他之前的父节点已经记录完毕,可以直接加入到他的子节点中. 最后还需要转换结果,从小到大,直接用s ...
- 拓扑排序之java实现_有向图和拓扑排序Java实现
package practice; import java.util.ArrayDeque; import java.util.Iterator; import java.util.Stack; pu ...
- 数据结构C++——拓扑排序
数据结构C++--拓扑排序 文章目录 数据结构C++--拓扑排序 一.前言 二.拓扑排序的概念及作用 三.拓扑排序的实现 ①拓扑排序的实现原理 ②拓扑排序中FindInDegree()函数的实现 ③拓 ...
- C/C++二级指针概念及应用(有向图的邻接表(拓扑排序)、有向网图的邻接表、树的孩子表示)
目录 一.概述 例1: 例2: 代码: 二.实例 1.有向图的邻接表(拓扑排序) 2.有向网图的邻接表 3.树的孩子表示 一.概述 二级指针:指向指针的指针.一般需要修改地址的时候会用到二级指针. 注 ...
- 【zz】如何去理解 拓扑排序算法
from http://www.cnblogs.com/shanyou/archive/2006/11/16/562861.html 查看Castle的代码,在Castle.Core中内部的数据结构采 ...
最新文章
- 独家 | 层级聚类和Python实现的初学者指南(附链接)
- oracle11g导出空表
- 语句 if else
- c#编程实战宝典 付强_C#开发实战宝典pdf
- 推荐工具 HBuilder
- OSPF多区域配置【eNSP实现】
- 计算机网络拓扑结构的分析,计算机网络拓扑结构分析
- 学拳录 23退步压肘
- MySQL查看表结构SQL语句
- 《花开半夏》--4 生死之间的吻(1)
- STM32F103-LED模块
- 夜光带你走进python开发 (三十九)传奇语言
- BTC交易标准分类(对比说明)
- ㉕AW-A33 Linux驱动开发之audio子系统驱动程序
- opensuse的快捷键
- 服务器开关电源型号ab和sb,SB21150AB 开关电源的PWM调整电流上升率
- 链路汇聚 Eth-trunk
- opencv常用函数整理
- 什么是wifi霸屏神器?用WiFi霸屏广告机打广告是什么体验?
- Google Play约会游戏开发者,ChinaJoy 2017完美收官!
热门文章
- Cocos Creator 优化,帧动画优化
- 程序员买房前后对比,看完后已哭瞎...
- 什么是JRE?Java运行环境简介
- uniapp设置导航栏、沉浸式导航栏以及获取屏幕尺寸
- 解决git拉取代码时报:Auto packing the repository in background for optimum performance
- 《敦煌》—— 读后总结
- 任务七、名片管理系统
- Kali-Linux安装驱动并使用Blueman连接蓝牙耳机
- 基于matlab在信号与系统仿真中的应用,基于MATLAB在信号与系统仿真中的应用
- 利用Python获取最新的sci论文摘要信息并群发邮箱