单源最短路径

题目描述

如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。

输入输出格式

输入格式:

第一行包含三个整数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)的更多相关文章

  1. POJ 2387 Til the Cows Come Home(最短路 Dijkstra/spfa)

    传送门 Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 46727   Acce ...

  2. ACM-最短路(SPFA,Dijkstra,Floyd)之最短路——hdu2544

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

  3. 【BZOJ-3627】路径规划 分层图 + Dijkstra + spfa

    3627: [JLOI2014]路径规划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 186  Solved: 70[Submit][Status] ...

  4. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  5. dijkstra spfa prim kruskal 总结

    最短路和最小生成树应该是很早学的,大家一般都打得烂熟,总结一下几个问题 一  dijkstra  O((V+E)lgV) //V节点数 E边数 dijkstra不能用来求最长路,因为此时局部最优解已经 ...

  6. POJ3662 [USACO08JAN]Telephone Lines (二分答案/分层图求最短路)

    这道题目有两种解法: 1.将每个点视为一个二元组(x,p),表示从起点到x有p条路径免费,相当于构建了一张分层图,N*k个节点,P*k条边.在这张图上用优先队列优化的SPFA算法求解,注意这里的d数组 ...

  7. 算法学习笔记(三) 最短路 Dijkstra 和 Floyd 算法

    图论中一个经典问题就是求最短路.最为基础和最为经典的算法莫过于 Dijkstra 和 Floyd 算法,一个是贪心算法,一个是动态规划.这也是算法中的两大经典代表.用一个简单图在纸上一步一步演算,也是 ...

  8. 最短路Dijkstra算法的一些扩展问题

    最短路Dijkstra算法的一些扩展问题     很早以前写过关于A*求k短路的文章,那时候还不明白为什么还可以把所有点重复的放入堆中,只知道那样求出来的就是对的.知其然不知其所以然是件容易引发伤痛的 ...

  9. Til the Cows Come Home 最短路Dijkstra+bellman(普通+优化)

    Til the Cows Come Home 最短路Dijkstra+bellman(普通+优化) 贝西在田里,想在农夫约翰叫醒她早上挤奶之前回到谷仓尽可能多地睡一觉.贝西需要她的美梦,所以她想尽快回 ...

随机推荐

  1. 四个O(n^2)级别的排序性能测试

    测试环境为DEV-C++,并且选择排序,插入排序,冒泡排序,均为优化后的,若想了解具体优化过程,请参照:https://blog.csdn.net/qq_40164152 测试用例: #ifndef ...

  2. angular ng-repeat出来的数据 每条修改数据后返回给接口 如何取到每个对应修改的值

    接口结构 $scope.DataList = [ { "dataA":"numA", "dataB":"numB"a } ...

  3. VUE 利用webpack 给生产环境和发布环境配置不同的接口地址

    第一步,分别设置不同的接口地址 首先,我们分别找到下面的文件: /config/dev.env.js /config/prod.env.js 其实,这两个文件就是针对生产环境和发布环境设置不同参数的文 ...

  4. cf1136D. Nastya Is Buying Lunch(贪心)

    题意 题目链接 给出一个排列,以及\(m\)个形如\((x, y)\)的限制,表示若\(x\)在\(y\)之前则可以交换\(x, y\). 问\(n\)位置上的数最多能前进几步 \(n \leqsla ...

  5. Android Studio 无法预览xml布局视图:failed to load AppCompat ActionBar with unkNown error

    问题如下: 解决方法: 找到res-->values-->styles.xml 文件 可以看到主题Them设置如下: 修改为: 界面预览可以正常显示

  6. Redis常用命令【字符串】

    1.启动Redis客户端 进入src目录下,执行:redis-cli启动Redis客户端 2.help 帮助 帮助命令,用来查看redis命令的使用方式 3.set 设置 3.1设置 3.2不存在才设 ...

  7. 如何定位那些SQL产生了大量的redo日志

    在ORACLE数据库的管理.维护过程中,偶尔会遇到归档日志暴增的情况,也就是说一些SQL语句产生了大量的redo log,那么如何跟踪.定位哪些SQL语句生成了大量的redo log日志呢? 下面这篇 ...

  8. [20190225]删除tab$记录的恢复5.txt

    [20190225]删除tab$记录的恢复5.txt --//昨天下午看了链接https://blog.csdn.net/Enmotech/article/details/87834503,大概知道对 ...

  9. SQL Server Browser探究

    一.官网关于SQL SERVER Browser服务的解释(谷歌翻译后稍作修改的): https://docs.microsoft.com/en-us/sql/tools/configuration- ...

  10. AspNet mvc的一个bug

    [HttpPost] public ActionResult updateLoan(TuWenMilitaryRank entity) 使用mvc绑定表单 每次绑定的对象都为null,查看Reques ...