图上最短路(Dijkstra, spfa)
单源最短路径
题目描述
如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。
输入输出格式
输入格式:
第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数、出发点的编号。
接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条有向边的出发点、目标点和长度。
输出格式:
一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为2147483647)
输入输出样例
输入样例
输出样例
单源最短路(Single-Source Shortest Paths, SSSP)
先上Dijkstra算法
Dikstra 算法适用于边权为正的情况。主要想法是:将一个点走一步能到达的所有结点都放进队列里,并从队列里选择源点到该点路径最短的结点出队。这样就保证出队的结点一定是源点到该点的最短路。那么就能确定放进队列的每一个结点不仅要有该结点的编号,也要有源点到该结点的距离,所以可以用结构体来实现。队列中出队的必须是最小的,那么就可以用优先队列实现。所以开一个结构体优先队列。
- #include<cstdio>
- #include<cmath>
- #include<iostream>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- #include<vector>
- using namespace std;
- const int maxn = 1e4 + ;
- const int INF = ;
- struct Grap
- {
- int num, cost; //num点编号,cost到该点距离
- bool operator < (const Grap& other)const
- /*优先队列出队的原本是最大的,而我们期望的是最小的,所
- 以重载小于号,不仅要兼容结构体,还要使逻辑相反 */
- {
- return cost > other.cost;
- }
- };
- vector<int>v[maxn];
- vector<int>c[maxn];
- int n, m, k, vis[maxn], dis[maxn];
- void dijkstra(int k)
- {
- for(int i = ; i < maxn; ++i)
- dis[i] = INF;
- /*初始化设为无穷,同时也代表了源点无法到达的点
- 的最短路径长度就是无穷*/
- memset(vis, , sizeof(vis));
- priority_queue<Grap>q;
- q.push((Grap){k, });
- dis[k] = ;
- while(!q.empty())
- {
- Grap now = q.top(); q.pop();
- int node = now.num;
- if(vis[node]) continue;
- /*如果该点已经出队,那到这个点的路径长度一定是最短路。为了防止
- 结点的重复扩展,如果发现新取出来的结点曾经被取出来过,应该直接
- 把它扔掉,所以开一个数组记录。 */
- vis[node] = ;
- for(int i = ; i < v[node].size(); ++i)
- {
- if(dis[v[node][i]] > dis[node] + c[node][i])
- {
- dis[v[node][i]] = dis[node] + c[node][i];
- q.push((Grap){v[node][i], dis[v[node][i]]});
- }
- }
- }
- }
- int main()
- {
- scanf("%d%d%d", &n, &m, &k);
- for(int i = ; i < m; ++i)
- {
- int a, b, cost; scanf("%d%d%d", &a, &b, &cost);
- v[a].push_back(b); c[a].push_back(cost); //用vector建图
- }
- dijkstra(k);
- for(int i = ; i <= n; ++i) printf("%d%s",dis[i], i == n ? "\n" : " ");
- return ;
- }
再上一个spfa算法
spfa算法不仅可以求最短路,也可以判断一个图中存不存在负圈。在这个算法中,一个结点可能多次入队(出队),最多入队 n 次(结点个数次),而当超过 n 次时,就证明一定存在负圈。
- #include <cstdio>
- #include<iostream>
- #include<cmath>
- #include<queue>
- #include<vector>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- vector<int>v[], c[];
- const int INF = ;
- int dis[];
- bool vis[];
- void spfa(int a)
- {
- for(int i = ; i < ; ++i) dis[i] = INF;
- dis[a] = ;
- memset(vis, , sizeof(vis));
- queue<int>q;q.push(a);
- while(!q.empty())
- {
- int now = q.front();q.pop();
- vis[now] = ; //出队后去除标记
- for(int i = ; i < (int)v[now].size(); ++i)
- {
- if(dis[now] + c[now][i] < dis[v[now][i]])
- {
- dis[v[now][i]] = dis[now] + c[now][i];
- if(!vis[v[now][i]])
- {q.push(v[now][i]); vis[v[now][i]] = ;}
- }
- }
- }
- }
- int main()
- {
- int n, m, s;
- scanf("%d%d%d", &n, &m, &s);
- for(int i = ; i < m; ++i)
- {
- int f, g, w;
- scanf("%d%d%d", &f, &g, &w);
- v[f].push_back(g);c[f].push_back(w);
- }
- spfa(s);
- for (int i = ; i <= n; i++) printf("%d%c", dis[i], i == n ? '\n' : ' ');
- }
图上最短路(Dijkstra, spfa)的更多相关文章
- POJ 2387 Til the Cows Come Home(最短路 Dijkstra/spfa)
传送门 Til the Cows Come Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 46727 Acce ...
- ACM-最短路(SPFA,Dijkstra,Floyd)之最短路——hdu2544
***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...
- 【BZOJ-3627】路径规划 分层图 + Dijkstra + spfa
3627: [JLOI2014]路径规划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 186 Solved: 70[Submit][Status] ...
- [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)
[Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...
- dijkstra spfa prim kruskal 总结
最短路和最小生成树应该是很早学的,大家一般都打得烂熟,总结一下几个问题 一 dijkstra O((V+E)lgV) //V节点数 E边数 dijkstra不能用来求最长路,因为此时局部最优解已经 ...
- POJ3662 [USACO08JAN]Telephone Lines (二分答案/分层图求最短路)
这道题目有两种解法: 1.将每个点视为一个二元组(x,p),表示从起点到x有p条路径免费,相当于构建了一张分层图,N*k个节点,P*k条边.在这张图上用优先队列优化的SPFA算法求解,注意这里的d数组 ...
- 算法学习笔记(三) 最短路 Dijkstra 和 Floyd 算法
图论中一个经典问题就是求最短路.最为基础和最为经典的算法莫过于 Dijkstra 和 Floyd 算法,一个是贪心算法,一个是动态规划.这也是算法中的两大经典代表.用一个简单图在纸上一步一步演算,也是 ...
- 最短路Dijkstra算法的一些扩展问题
最短路Dijkstra算法的一些扩展问题 很早以前写过关于A*求k短路的文章,那时候还不明白为什么还可以把所有点重复的放入堆中,只知道那样求出来的就是对的.知其然不知其所以然是件容易引发伤痛的 ...
- Til the Cows Come Home 最短路Dijkstra+bellman(普通+优化)
Til the Cows Come Home 最短路Dijkstra+bellman(普通+优化) 贝西在田里,想在农夫约翰叫醒她早上挤奶之前回到谷仓尽可能多地睡一觉.贝西需要她的美梦,所以她想尽快回 ...
随机推荐
- 13 ,CSS 入门基础,行内排版内嵌式排版和外部排版样式
1.认识 CSS 2.传统 HTML 设计网页版面的缺点 3.CSS 的特点 4.CSS 的排版样式 13.1 认识CSS CSS的英文全名是 Cascading Style Sheets,中文可翻译 ...
- python之把字符串形式的函数编译执行
实现效果:执行字符串形式的函数 代码如下 # name = 'aaa' # data = [18,32,33] # def hellocute(): # return "name %s ,a ...
- [待优化笔记]原生JS实现验证框架 checkFun
;(function(){ /** 验证框架 checkFun * 使用方法: * <input class="required" type="text" ...
- iOS开发GCD(3)-数据安全
/* 多个线程可能访问同一块资源,造成数据错乱和数据安全问题 为代码添加同步锁(互斥锁) */ -(void)synchronized{ @synchronized(self){ //需要锁住的代码, ...
- c++趣味之返回void
void a(){} void b(){return a();} int main() { b(); ; } 这个是能编译的(vs,gcc),void函数是能返回,一般不会这么写,但是这样确实可以.你 ...
- mysql学习之完整的select语句
本文内容: 完整语法 去重选项 字段别名 数据源 where group by having order by limit 首发日期:2018-04-11 完整语法: 先给一下完整的语法,后面将逐一来 ...
- python之restful api(flask)获取数据
需要用到谷歌浏览器的扩展程序 Advanced Rest Client进行模拟请求 1.直接上代码 from flask import Flask from flask import request ...
- SQL Server将一列的多行内容拼接成一行
昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行 比如表中有两列数据 : ep_classes ep_name A ...
- 自动化测试基础篇--Selenium cookie操作
摘自https://www.cnblogs.com/sanzangTst/p/8376471.html 在验证浏览器中cookie是否正确时,有时基于真实cookie的测试是无法通过白盒和集成测试进行 ...
- MySQL各类SQL语句的加锁机制
官网参考:https://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html MySQL把读操作分为两大类:锁定读和非锁定读(即locking ...