图上最短路(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(普通+优化) 贝西在田里,想在农夫约翰叫醒她早上挤奶之前回到谷仓尽可能多地睡一觉.贝西需要她的美梦,所以她想尽快回 ...
随机推荐
- Eclipse中SVN插件的安装和配置(在线安装)
公司项目中用到了svn来管理项目,然后需要在Eclipse中进行配置.网上参考了很多资料,离线安装的方式装上了,但是导入项目后报错,可能是离线安装包的问题.然后又采用了Eclipse在线安装的方式,总 ...
- awk、nawk、mawk、gawk的简答介绍
awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理.数据可以来自标准输入.一个或多个文件,或其它命令的输出(即管道).它支持用户自定义函数和 动态正则表达式等先进功能,是linu ...
- matlab rank
k =rank(A) %a is matrix s = svd(A); tol = max(size(A))*eps(max(s)); r = sum(s > tol);
- laravel使用Schema创建数据表
1.简介 迁移就像数据库的版本控制,允许团队简单轻松的编辑并共享应用的数据库表结构,迁移通常和Laravel的schema构建器结对从而可以很容易地构建应用的数据库表结构.如果你曾经告知小组成员需要手 ...
- es6 语法 (对象扩展)
{ //简洁表示法 let o = 1; let k = 2; let es5 = { o:o, k:k }; let es6 = { o,k }; console.log(es5,es6); //1 ...
- BZOJ1101: [POI2007]Zap(莫比乌斯反演)
1101: [POI2007]Zap Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2951 Solved: 1293[Submit][Status ...
- 一个AI产品经理怎么看AI的发展
一个AI产品经理怎么看AI的发展 https://www.jianshu.com/p/bed6b22ae837 最近一直在思考这个问题,人工智能接下来的几年会有什么样的发展,是否真的能够在很多工作岗位 ...
- neutron 多租户隔离的实现以及子网间路由的实现
1.一个network相当于一个二层网络,使用vxlan 隧道连通所有的CNA节点. 2.一个VPC下有多个network,也就是会分配多个vxlan隧道,这些子网间的路由是通过DVR实现的.DVR就 ...
- IntelliJ IDEA安装、配置、测试
IntelliJ IDEA安装.配置.测试(win7_64bit) 目录 1.概述 2.本文用到的工具 3.安装.激活与配置 4.开发测试 4.1 JavaSE开发测试(确保JDK已正确安装) 4.2 ...
- Kotlin入门(27)文件读写操作
Java的文件处理用到了io库java.io,该库虽然功能强大,但是与文件内容的交互还得通过输入输出流中转,致使文件读写操作颇为繁琐.因此,开发者通常得自己重新封装一个文件存取的工具类,以便在日常开发 ...