题目链接: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. E. Anton and Tree 数组开大点

    http://codeforces.com/contest/734/problem/E 看了题解,缩点 + 树的直径. 然而一直wa14. 注意到, 缩点后重建图,在5的时候,5和6建了一条边,然后6 ...

  2. Apache Kylin的架构特性

    不多说,直接上干货! http://kylin.apache.org/cn/ 可扩展的超快OLAP引擎,提供标准SQL查询接口 支持单机或集群部署,为减少在Hadoop上百亿规模数据查询延迟而设计: ...

  3. 解决vue跨域问题

    package com.qmtt.config; import java.io.IOException; import javax.servlet.Filter; import javax.servl ...

  4. AJPFX总结I/O流操作(二)

    FileWriter:该类没有特有的方法只有自己的构造函数.该类特点在于1,用于处理文本文件.2,该类中有默认的编码表,3,该类中有临时缓冲.构造函数:在写入流对象初始化时,必须要有一个存储数据的目的 ...

  5. hash系列集合的性能优化

    hash系列的集合: HashSet.LinkedHashSet     采用hash算法决定元素在集合中的存储位置 HashMap.LinkedHashMap.Hashtable   采用hash算 ...

  6. 【HEVC简介】DB-DeBlock Filter

    参考论文:HEVC Deblocking Filter <HEVC标准介绍.HEVC帧间预测论文笔记>系列博客,目录见:http://www.cnblogs.com/DwyaneTalk/ ...

  7. ICEcoder显示汉字出现乱码的处理

    在网上看到icecoder这个小东西,是一个基于web的编辑器,很不错.唯一的缺点是打开的文件中汉字会变成乱码. 经查看源代码,在lib/file-control.php中,第89行是: echo ' ...

  8. 项目中非常有用并且常见的ES6语法

    今天闲着无事,梳理下ES6常见的语法知识点:除此之外的知识点自行细化和梳理! <!DOCTYPE html> <html> <head> <meta char ...

  9. UVA 10900 So you want to be a 2n-aire? 2元富翁 (数学期望,贪心)

    题意:你一开始有1元钱,接下来又n<=30个问题,只需答对1个问题手上的钱就翻倍,最多答对n个,得到的钱是2n.而每个问题答对的概率是[t,1]之间平均分布,那么问最优情况下得到奖金的期望值是多 ...

  10. 北京区域赛I题,Uva7676,A Boring Problem,前缀和差分

    转载自https://blog.csdn.net/weixin_37517391/article/details/83821752 题解 其实这题不难,只要想到了前缀和差分就基本OK了. 我们要求的是 ...