题目链接

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+css3实现旋转效果

    我的前面一张文章实现了用css3制作旋转的效果,现在呢,我换另外一种方法来实现.就是使用js结合css3的方法来实现的.下面我就先上图给大家看看效果吧 下面呢我先放上我的css代码,代码很简单: .o ...

  2. Typora 自定义主题 修改左右间距

    打开偏好设置,打开主题文件夹 比如要修改night主题中的间距,编辑night.css文件,修改#write样式即可. 修改其他样式类试.

  3. CF869 C 组合

    先吐槽下,题面套的物语系列欸.. 由于距离为3,那么必定两种颜色间要填入第3种颜色,否则就是单独点的情况,那么两两之间可以单独考虑而不影响答案,枚举两种颜色之间边数,计算一边的组合和另一边的排列,最后 ...

  4. Linux启动的流程

    2017年1月10日, 星期二 Linux启动的流程   null

  5. Backbone基础笔记

    之前做一个iPad的金融项目的时候有用到Backbone,不过当时去的时候项目已经进入UAT测试阶段了,就只是改了改Bug,对Backbone框架算不上深入了解,但要说我一点都不熟悉那倒也不是,我不太 ...

  6. 【AtCoder Grand Contest 007E】Shik and Travel [Dfs][二分答案]

    Shik and Travel Time Limit: 50 Sec  Memory Limit: 512 MB Description 给定一棵n个点的树,保证一个点出度为2/0. 遍历一遍,要求每 ...

  7. js延迟几秒执行

    var t=setTimeout("location.reload()",5000);

  8. 问题 1476: [蓝桥杯][基础练习VIP]龟兔赛跑预测 (模拟)

    题目链接 题目描述 话说这个世界上有各种各样的兔子和乌龟,但是 研究发现,所有的兔子和乌龟都有一个共同的特点--喜欢赛跑.于是世界上各个角落都不断在发生着乌龟和兔子的比赛,小华对此很感兴趣,于是决定研 ...

  9. Python练习-一个简单易懂的迭代器,了解一下

    今天我们学习了迭代器,其实可以理解为是一个元素容器被遍历的方式,不难理解,看看下面的小例子: # 编辑者:闫龙 #一个简单的迭代器 l = [1,2,3,4,5,6,7]#建立一个列表l ite = ...

  10. Visual Studio 2010 SP1 在线安装后,找到缓存在本地的临时文件以便下次离线安装

    由于在下载Visual Studio 2010安装程序(大约3G左右)的时候速度飞快,大约几分钟下载完毕(多线程下载工具下载),所以笔者在继续安装Visual Studio 2010 SP1的时候也选 ...