题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1874

Problem Description
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
 
Input
本题目包含多组数据,请处理到文件结束。 每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。 接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。 再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
 
Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
 
在这道题中因为数据量不大,所以用四种最短路径的方法都可以对它进行求解,也用这道题来令自己熟悉一下四种最短路径的算法:
 
Dijkstra:
 #include <cstdio>
#include <algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef pair<int,int> pii;
#define N 205
#define M 1005
#define MAXN 0x3f3f3f3f
int y[M],d[M],next[M];
int first[N],dp[N];
int k; //写完函数后这两句话老是忘记写,所以还是这样一开始就写在一个函数里这样自己就不会忘了
void init()
{
k=;
memset(first,-,sizeof(first));
}
void add(int a,int b,int c)
{
y[k]=b,d[k]=c,next[k]=first[a];
first[a]=k;
k++;
} void dijkstra(int src)
{
priority_queue<pii,vector<pii>,greater<pii> > q;
memset(dp,0x3f,sizeof(dp));
dp[src]=,q.push(make_pair(,src));
while(!q.empty()){
while(!q.empty()&&dp[q.top().second]<q.top().first) q.pop();
if(q.empty()) break;
int u=q.top().second;
q.pop();
for(int i=first[u];i!=-;i=next[i]){
if(dp[y[i]]>dp[u]+d[i]){
dp[y[i]]=dp[u]+d[i];
q.push(make_pair(dp[y[i]],y[i]));
}
}
}
} int main()
{
int n,m,a,b,c,s,t;
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=;i<m;i++){
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
scanf("%d%d",&s,&t);
dijkstra(s);
if(dp[t]<MAXN) printf("%d\n",dp[t]);
else printf("%d\n",-);
} return ;
}
SPFA:
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define MAXN 20010
#define N 205
int v[MAXN],d[MAXN],next[MAXN],first[N],visit[N],dp[N];
int k;//k表示路的条数 void add(int x,int y,int a)//这里添加的是无向图的边,所以进行两次
{
v[k]=y;
next[k]=first[x];
d[k]=a;
first[x]=k;
k++;
v[k]=x;
next[k]=first[y];
d[k]=a;
first[y]=k;
k++;
} int spfa(int a,int b)
{
memset(dp,0x3f,sizeof(dp));
//memset(visit,0,sizeof(visit));//这一段是没有必要的,每次spfa做完,他都会最后变为0
queue<int> q;
dp[a]=,visit[a]=;
q.push(a);
while(!q.empty()){
int c=q.front();
q.pop();
visit[c]=;
for(int i=first[c];i!=-;i=next[i]){
if(dp[v[i]]>dp[c]+d[i]){
dp[v[i]]=dp[c]+d[i];
if(!visit[v[i]]) q.push(v[i]),visit[v[i]]=;
}
}
}
if(dp[b]<0x3f3f3f3f) return dp[b];
else return -;
} int main()
{
int n,m,start,End,x,y,a;
while(scanf("%d%d",&n,&m)!=EOF){
k=;
memset(next,-,sizeof(next));
memset(first,-,sizeof(first));
for(int i=;i<m;i++){
scanf("%d%d%d",&x,&y,&a);
add(x,y,a);
}
scanf("%d%d",&start,&End);
printf("%d\n",spfa(start,End));
}
return ;
}

Floyd:

在使用Floyd时应该把矩阵每个点一开始做好初始化,主对角线上均为0;

其他定位一个最大值。

PS:这道题比较坑的地方是两地间可以有多条路,我们要判断是否为较小的路放入矩阵中

floyd是基于建立在2维矩阵中的,每次更新出一个到达 i 的最短路径,都要遍历一次矩阵,把所有其他节点到 i 点最小值不断更新出来,因为这道题城镇数目比较少,可以采取这种

复杂度为O(n^3)的方法,但是通过这个方法我们可以确定任意一点到其他点的最短路径(自我感觉类似于打表法,有木有?!),不像SPFA做一次只能找到你所需的最短路径

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 205
#define MAXN 0x3f3f3f3f
int mat[N][N]; void Floyd(int n)//为n*n的矩阵
{
for(int i=;i<n;i++){
for(int j=;j<n;j++){
for(int k=;k<n;k++){
if(mat[j][k]>mat[j][i]+mat[k][i])
mat[j][k]=mat[j][i]+mat[k][i];//i只是用来计更新次数的,实际上每更新一次,都要将整个矩阵的所有点都遍历一遍
} //所以是mat[j][k];
}
}
}
int main()
{
int n,m,start,End,x,y,a;
while(scanf("%d%d",&n,&m)!=EOF){
memset(mat,0x3f,sizeof(mat));
for(int i=;i<n;i++) mat[i][i]=;
for(int i=;i<m;i++){
scanf("%d%d%d",&x,&y,&a);
a=min(a,mat[x][y]);
mat[x][y]=a,mat[y][x]=a;//在这里要判断一下,因为两地之间可以有多条路,我们需要判断它到底是否为我们要的最短路
}
scanf("%d%d",&start,&End);
Floyd(n);
if(mat[start][End]<MAXN) printf("%d\n",mat[start][End]);
else printf("-1\n");
}
return ;
}

BellMan-ford:

在写BellMan时,没必要写first[]数组了

它执行一次只能找到固定对应的a到b的最短距离,在这一点上是远远不如Floyd的,而且复杂度为O(n*k),在数据量特别大时是不适用的

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 205
#define M 20005
#define MAXN 0x3f3f3f3f
int u[M],v[M],d[M],k;
int dp[N];
void add(int x,int y,int a)
{
u[k]=x,v[k]=y,d[k]=a;
k++;
}
void BellMan(int n,int src)
{
memset(dp,0x3f,sizeof(dp));
dp[src]=;
for(int i=;i<n;i++)
{
for(int j=;j<k;j++)
if(dp[v[j]]>dp[u[j]]+d[j])
dp[v[j]]=dp[u[j]]+d[j];
}
}
int main()
{
int n,m,start,End,x,y,a;
while(scanf("%d%d",&n,&m)!=EOF){
k=;
for(int i=;i<m;i++){
scanf("%d%d%d",&x,&y,&a);
add(x,y,a);
add(y,x,a);
}
scanf("%d%d",&start,&End);
BellMan(n,start);
if(dp[End]<MAXN) printf("%d\n",dp[End]);
else printf("-1\n");
}
return ;
}

HDU 1874 最直接的最短路径问题的更多相关文章

  1. HDU 1874 畅通project续 最短路径入门(dijkstra)

    Problem Description 某省自从实行了非常多年的畅通project计划后,最终修建了非常多路.只是路多了也不好,每次要从一个城镇到还有一个城镇时,都有很多种道路方案能够选择,而某些方案 ...

  2. HDU 1874 畅通project续 (最短路径)

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

  3. ACM: HDU 1874 畅通工程续-Dijkstra算法

    HDU 1874 畅通工程续 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Desc ...

  4. (重刷)HDU 1874 畅通工程续 + HDU 2544 最短路 最短路水题,dijkstra解法。

    floyd解法 今天初看dijkstra,先拿这两题练手,其他变形题还是不是很懂. 模版题,纯练打字... HDU 1874: #include <cstdio> #define MAXN ...

  5. hdu 2544 hdu 1874 poj 2387 Dijkstra 模板题

    hdu 2544  求点1到点n的最短路  无向图 Sample Input2 1 //结点数 边数1 2 3 //u v w3 31 2 52 3 53 1 20 0 Sample Output32 ...

  6. POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / SCU 1132 Invitation Cards / ZOJ 2008 Invitation Cards / HDU 1535 (图论,最短路径)

    POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / ...

  7. HDU 1874 畅通工程续-- Dijkstra算法详解 单源点最短路问题

    参考 此题Dijkstra算法,一次AC.这个算法时间复杂度O(n2)附上该算法的演示图(来自维基百科): 附上:  迪科斯彻算法分解(优酷) problem link -> HDU 1874 ...

  8. HDU - 1874 畅通工程续(最短路径)

    d.已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离. s.最短路径 c.Dijkstra单源最短路 /* Dijkstra单源最短路 权值必须是非负 单源最短路径,Dijkstra算法 ...

  9. hdu 1874 畅通工程续 Dijkstra

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1874 题目分析:输入起点和终点,顶点的个数,已连通的边. 输出起点到终点的最短路径,若不存在,输出-1 ...

随机推荐

  1. 记一次有关spark动态资源分配和消息总线的爬坑经历

    问题: 线上的spark thriftserver运行一段时间以后,ui的executor页面上显示大量的active task,但是从job页面看,并没有任务在跑.此外,由于在yarn mode下, ...

  2. C#之九大视图

    本节向大家介绍一下有关UML视图方面的内容,UML视图共有9种,它们之间有什么区别和联系呢,下面就让我们一起来学习吧,相信通过本节的介绍你一定会有不少收获. UML视图 UML总共提供了9种视图,这些 ...

  3. Koa--基于Node.js平台的下一代web开发框架的安装

    koa 是由 Express 原班人马打造的,致力于成为一个更小.更富有表现力.更健壮的 Web 框架. 使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函 ...

  4. toast插件的简单封装(样式适用pc后台管理系统的场景)

    直接分三个步骤吧: 1.手写一个toast.vue组件 <template> <transition name="toast-fade"> <div ...

  5. IntelliJ IDEA openfire 使用IntelliJ IDEA 部署OPENFIRE 服务端

    用MyEclipse部署OF的步骤,网上有很多,可以自行google,这里要记录的是用据说最好用的JAVA编辑器IntelliJ IDEA来部署OF服务端.试了好多下,终于成功了,记录下. 直接上图吧 ...

  6. Git理论知识补充

    转自: http://www.cnblogs.com/hnrainll/archive/2012/11/13/2768003.html 对于任何一个文件,在 Git 内都只有三种状态:已提交(comm ...

  7. laravel composer 扩展包开发(超详细)

    laravel composer 扩展包开发(超详细) 置顶 2018年02月05日 11:09:16 Simael__Aex 阅读数:10396    版权声明:转载请注明出处:http://blo ...

  8. Java中System.setProperty()用法

    /*  * 设置指定键对值的系统属性  * setProperty (String prop, String value);  *  * 参数:  * prop - 系统属性的名称.  * value ...

  9. MFC不同分辨率和缩放下正常显示的方法

    方法1:为了满足Windows操作系统上不同分辨率下的显示,我们在OnPaint中重绘.

  10. vueshengmingzhouqi

    首先,每个Vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期.首先看一张图吧~这是官方文档上的图片相信大家一定都会很熟悉: 可以看到在vue一整个的生命周期中会有很多钩子函 ...