题目链接

http://poj.org/problem?id=1847

题意

有n个车站,编号1~n,每个车站有k个出口,车站的出口默认是k个出口中的第一个,如果不想从默认出口出站,则需要手动选择出站口。现在从车站a出发,求最少需要手动选择几次出站口才能到车站b。

思路

这题的图中没有显式给出结点之间的距离,但可以根据题意给路径添加距离,比如测试数据中的“2 2 3”表示从第1个车站默认开往第2个车站,想要开到第3个车站则需手动选择,所以我们可以令结点1到结点2的边权值为0(默认车站),结点1到结点3边权值为1(需手动选择的车站),这样就可以使用Dijkstra算法、Floyd算法或者SPFA算法求解a,b之间的最短路,a,b之间最短路的值即是需手动选择车站的次数。

代码

Dijkstra算法和Floyd算法:

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std; const int INF = 0x3f3f3f;
const int N = + ;
int map[N][N];
int dist[N];
int visit[N];
int n, a, b; void dijkstra() //Dijkstra算法
{
memset(visit, , sizeof(visit));
for (int i = ; i <= n; i++)
dist[i] = map[a][i];
dist[a] = ;
visit[a] = ;
int min_dist, now = a;
for (int i = ; i <= n; i++)
{
min_dist = INF;
for (int j = ; j <= n; j++)
{
if (!visit[j] && dist[j] < min_dist)
{
min_dist = dist[j];
now = j;
}
}
visit[now] = ;
for (int j = ; j <= n; j++)
dist[j] = min(dist[j], dist[now] + map[now][j]);
}
if (dist[b] >= INF) //注意是dist[b]>=INF,不是dist[b]==INF
puts("-1");
else printf("%d\n", dist[b]);
} void floyd() //Floyd算法
{
for (int k = ; k <= n; k++)
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
if (map[a][b] >= INF)
puts("-1");
else printf("%d\n", map[a][b]);
} int main()
{
//freopen("poj1847.txt", "r", stdin);
while (scanf("%d%d%d", &n, &a, &b) == )
{
memset(map, INF, sizeof(map));
int k, t;
for (int i = ; i <= n; i++)
{
scanf("%d", &k);
for (int j = ; j <= k; j++)
{
scanf("%d", &t);
if (j == )
map[i][t] = ;
else map[i][t] = ;
}
}
dijkstra();
//floyd();
}
return ;
}

SPFA算法:

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std; struct Edge
{
int s, e, dist; Edge() {}
Edge(int s, int e, int d) :s(s), e(e), dist(d) {}
}; const int INF = 0x3f3f3f;
const int N = + ;
vector<Edge> v[N];
int dist[N];
int visit[N];
int n, a, b; void spfa(int s)
{
queue<int> q;
memset(dist, INF, sizeof(dist));
memset(visit, , sizeof(visit));
q.push(s);
visit[s] = ;
dist[s] = ; while (!q.empty())
{
int s = q.front();
q.pop();
visit[s] = ;
for (int i = ; i < v[s].size(); i++)
{
int e = v[s][i].e;
if (dist[e] > dist[s] + v[s][i].dist)
{
dist[e] = dist[s] + v[s][i].dist;
if (!visit[e])
{
visit[e] = ;
q.push(e);
}
}
}
}
if (dist[b] >= INF)
puts("-1");
else printf("%d\n", dist[b]);
} int main()
{
//freopen("poj1847.txt", "r", stdin);
while (scanf("%d%d%d", &n, &a, &b) == )
{
for (int i = ; i <= n; i++)
v[i].clear(); int k, t;
for (int i = ; i <= n; i++)
{
scanf("%d", &k);
for (int j = ; j <= k; j++)
{
scanf("%d", &t);
if (j == )
v[i].push_back(Edge(i, t, ));
else v[i].push_back(Edge(i, t, ));
}
}
spfa(a); //求结点a到其余各点的最短路径
}
return ;
}

poj1847 Tram(Dijkstra || Floyd || SPFA)的更多相关文章

  1. hdoj2544 最短路(Dijkstra || Floyd || SPFA)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2544 思路 最短路算法模板题,求解使用的Dijkstra算法.Floyd算法.SPFA算法可以当做求解 ...

  2. HDU——1874畅通工程续(Dijkstra与SPFA)

    畅通工程续 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  3. 稀疏图(邻接链表),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)

    全部函数通过杭电 1142,1162,1198,1213等题目测试. #include<iostream> #include<vector> #include<queue ...

  4. 稠密图(邻接矩阵),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)

    全部函数通过杭电 1142,1162,1198,1213等题目测试. #include<iostream> #include<vector> #include<queue ...

  5. 【算法】狄克斯特拉算法(Dijkstra’s algorithm)

    狄克斯特拉算法(Dijkstra’s algorithm) 找出最快的路径使用算法——狄克斯特拉算法(Dijkstra’s algorithm). 使用狄克斯特拉算法 步骤 (1) 找出最便宜的节点, ...

  6. O - Layout(差分约束 + spfa)

    O - Layout(差分约束 + spfa) Like everyone else, cows like to stand close to their friends when queuing f ...

  7. 几大最短路径算法比较(Floyd & Dijkstra & Bellman-Ford & SPFA)

    几个最短路径算法的比较:Floyd 求多源.无负权边(此处错误?应该可以有负权边)的最短路.用矩阵记录图.时效性较差,时间复杂度O(V^3).       Floyd-Warshall算法(Floyd ...

  8. 四大算法解决最短路径问题(Dijkstra+Bellman-ford+SPFA+Floyd)

    什么是最短路径问题? 简单来讲,就是用于计算一个节点到其他所有节点的最短路径. 单源最短路算法:已知起点,求到达其他点的最短路径. 常用算法:Dijkstra算法.Bellman-ford算法.SPF ...

  9. 最短路径:(Dijkstra & Floyd)

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Di ...

随机推荐

  1. js-验证码插件gVerify.js

    插件 gVerify.js 源码 !(function(window, document) { function GVerify(options) { //创建一个图形验证码对象,接收options对 ...

  2. android textview空格占位符以及一些其他占位符汇总

    == 普通的英文半角空格   ==   ==   == no-break space (普通的英文半角空格但不换行)   == 中文全角空格 (一个中文宽度)   ==   == en空格 (半个中文 ...

  3. Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第七部分(Page 12)

    编写你的第一个 Django app,第七部分(Page 12)转载请注明链接地址 本节教程承接第六部分(page 11)的教程.我们继续开发 web-poll应用,并专注于自定义django的自动生 ...

  4. bootstrap使用记录

    http://v3.bootcss.com/components/#panels http://v2.bootcss.com/components.html

  5. Lucene之Java实战

    1.导包 2.索引的创建 2.1首先,我们需要定义一个词法分析器. Analyzer analyzer = new IKAnalyzer();//官方推荐 Analyzer analyzer = ne ...

  6. 为什么C++空类的实例大小为1

    [为什么C++空类的实例大小为1] 每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址.所以大小为1. 参考 ...

  7. Windows上安装QT4后更改MinGW的路径

    在windows上安装使用MinGW的QT4时,并不会一起安装MinGW. 在安装过程中,会让你指定已经安装的MinGW的路径. 当你使用QT4时,将使用你指定的MinGW的路径下的g++来编译构建程 ...

  8. bzoj 1564 [NOI2009]二叉查找树(树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1564 [题意] 给定一个Treap,总代价为深度*距离之和.可以每次以K的代价修改权值 ...

  9. Spark1.3.1 On Yarn的集群搭建

    下面给出的是spark集群搭建的环境: 操作系统:最小安装的CentOS 7(下载地址) Yarn对应的hadoop版本号:Hadoop的Cloudera公司发行版Hadoop2.6.0-CDH5.4 ...

  10. Python练习-无参装饰器的正确打开方式

    import time def DecoUserPrint(UserFunc):#定义一个DecoUserPrint接收参数的多重方法 def DecoPrint(): StartTime = tim ...