最短路径问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 20555    Accepted Submission(s):
6098

Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
 
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数
a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数
s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
 
Output
输出 一行有两个数, 最短距离及其花费。
 
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
 
Sample Output
9 11
 
Source
 
Recommend
notonlysuccess   |   We have carefully selected several
similar problems for you:  1142 2680 1385 1598 1596 
 
同样是最短路的模板题,不过加入了花费这个元素,当路程相同时,选择花费小的方案,还是比较好处理的。
 
题意:中文题,很好理解。
 
附上代码:
 
 #include <iostream>
#include <cstdio>
#include <cstring>
#define M 1005
#define MAX 0x3f3f3f3f
using namespace std;
int map[M][M],vis[M],dis[M],money[M][M],r[M];
int main()
{
int n,m,i,j,s,t;
while(~scanf("%d%d",&n,&m))
{
if(!n&&!m) break;
memset(vis,,sizeof(vis));
memset(dis,,sizeof(dis));
memset(r,,sizeof(r));
for(i=; i<=n; i++)
for(j=; j<=n; j++)
{
if(i==j) map[i][j]=,money[i][j]=;
else map[i][j]=MAX,money[i][j]=MAX;
}
int a,b,c,d;
while(m--)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
if(map[a][b]>c)
{
map[a][b]=c,map[b][a]=c;
money[a][b]=d,money[b][a]=d;
}
}
scanf("%d%d",&s,&t);
vis[s]=;
for(i=; i<=n; i++)
{
dis[i]=map[s][i];
r[i]=money[s][i];
}
int w,min;
for(i=; i<=n; i++)
{
min=MAX;
for(j=; j<=n; j++)
if(!vis[j]&&min>dis[j])
{
min=dis[j];
w=j;
}
vis[w]=;
for(j=; j<=n; j++)
{
if(!vis[j]&&map[w][j]<MAX)
{
if(dis[j]>dis[w]+map[w][j])
{
dis[j]=dis[w]+map[w][j];
r[j]=r[w]+money[w][j];
}
else if(dis[j]==dis[w]+map[w][j] && r[j]>r[w]+money[w][j]) //路程相同时,花费的处理
r[j]=r[w]+money[w][j];
}
}
}
printf("%d %d\n",dis[t],r[t]);
}
return ;
}

邻接表:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define M 1005
#define N 100005
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
int n,m,s,t,tol;
struct Edge
{
int from,to,val,p;
int next;
} edge[N*];
int head[N*],dis[M],r[M];
bool vis[M]; void init()
{
tol=;
memset(head,-,sizeof(head));
} void addEdge(int u,int v,int val,int p)
{
edge[tol].from=u;
edge[tol].to=v;
edge[tol].val=val;
edge[tol].p=p;
edge[tol].next=head[u];
head[u]=tol++;
edge[tol].from=v;
edge[tol].to=u;
edge[tol].val=val;
edge[tol].p=p;
edge[tol].next=head[v];
head[v]=tol++;
} void getmap()
{
int i,j;
int a,b,c,d;
while(m--)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
addEdge(a,b,c,d);
}
scanf("%d%d",&s,&t);
memset(dis,INF,sizeof(dis));
memset(r,INF,sizeof(r));
memset(vis,false,sizeof(vis));
} void spfa()
{
queue<int>q;
q.push(s);
dis[s]=;
r[s]=;
vis[s]=true;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].val)
{
dis[v]=dis[u]+edge[i].val;
r[v]=r[u]+edge[i].p;
if(!vis[v])
{
vis[v]=true;
q.push(v);
}
}
else if(dis[v]==dis[u]+edge[i].val)
{
if(r[v]>r[u]+edge[i].p)
{
r[v]=r[u]+edge[i].p;
if(!vis[v])
{
vis[v]=true;
q.push(v);
}
}
}
}
}
printf("%d %d\n",dis[t],r[t]);
return;
} int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==&&m==) break;
init();
getmap();
spfa();
}
return ;
}

hdu 3790 最短路径问题(迪杰斯特拉)的更多相关文章

  1. c/c++ 图的最短路径 Dijkstra(迪杰斯特拉)算法

    c/c++ 图的最短路径 Dijkstra(迪杰斯特拉)算法 图的最短路径的概念: 一位旅客要从城市A到城市B,他希望选择一条途中中转次数最少的路线.假设途中每一站都需要换车,则这个问题反映到图上就是 ...

  2. 最短路径之迪杰斯特拉算法(Java)

    1)Dijkstra算法适用于求图中两节点之间最短路径 2)Dijkstra算法设计比较巧妙的是:在求源节点到终结点自底向上的过程中,源节点到某一节点之间最短路径的确定上(这也是我之前苦于没有解决的地 ...

  3. 最短路径之迪杰斯特拉(Dijkstra)算法

    迪杰斯特拉(Dijkstra)算法主要是针对没有负值的有向图,求解其中的单一起点到其他顶点的最短路径算法.本文主要总结迪杰斯特拉(Dijkstra)算法的原理和算法流程,最后通过程序实现在一个带权值的 ...

  4. 最短路径之迪杰斯特拉(Dijkstra)算法

    对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点为源点,最后一个顶点为终点.最短路径的算法主要有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd ...

  5. JS实现最短路径之迪杰斯特拉(Dijkstra)算法

    最短路径: 对于网图来说,最短路径是指两个顶点之间经过的边上权值和最少的路径,我们称第一个顶点是源点,最后一个顶点是终点 迪杰斯特拉 ( Dijkstra) 算法是并不是一下子就求出 了 Vo 到V8 ...

  6. 最短路径之迪杰斯特拉算法的Java实现

    Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法.该算法被称为是“贪心算法”的成功典范.本文接下来将尝试以最通俗的语言来介绍这个伟大的算法,并赋予java实现代码. 一.知识准备 ...

  7. 图(最短路径算法————迪杰斯特拉算法和弗洛伊德算法).RP

    文转:http://blog.csdn.net/zxq2574043697/article/details/9451887 一: 最短路径算法 1. 迪杰斯特拉算法 2. 弗洛伊德算法 二: 1. 迪 ...

  8. hdu 3339 In Action(迪杰斯特拉+01背包)

    In Action Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  9. HDU 2680 最短路 迪杰斯特拉算法 添加超级源点

    Choose the best route Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  10. 最短路径算法-迪杰斯特拉(Dijkstra)算法在c#中的实现和生产应用

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先遍历思想),直到扩展到终点为止 贪心算法(Greedy ...

随机推荐

  1. javascript函数式编程和链式优化

    1.函数式编程理解 函数式编程可以理解为,以函数作为主要载体的编程方式,用函数去拆解.抽象一般的表达式 与命令式相比,这样做的好处在哪?主要有以下几点: (1)语义更加清晰 (2)可复用性更高 (3) ...

  2. web前端学习(二)html学习笔记部分(5)--拖放元素、canvas画布使用

    1.2.11  拖放 1.2.11.1  html拖放 1.2.11.2  html拖放本次资源 showOjb(一个对象)展示一下一个对象的信息. 1.2.12  html画布(canvas)  标 ...

  3. LintCode_488 快乐数

    题目 写一个算法来判断一个数是不是"快乐数". 一个数是不是快乐是这么定义的:对于一个正整数,每一次将该数替换为他每个位置上的数字的平方和,然后重复这个过程直到这个数变为1,或是无 ...

  4. js判断类型为数字的方法实现总汇——原生js判断isNumber()

    方法一[推荐]: 最容易想到的是用typeof来判断是否是number类型 ,但是如果为NaN会被认为也是number类型,因此我们需要使用isNaN来排除NaN的情况. function isNum ...

  5. AndroidStudio离线打包MUI

    1.下载5+SKD http://ask.dcloud.net.cn/article/103 2.解压到任意目录 3.导入HBuilder-Hello项目 4.在AndroidManifest.xml ...

  6. 【JZOJ3214】【SDOI2013】方程

    ╰( ̄▽ ̄)╭ 给定方程 X1+X 2+-+Xn=m 我们对第 1.. n1 个变量 进行一些限制 : X1≤A1 X2≤A2 - Xn1 ≤An1 我们对第 n1+1.. n1+1.. n1+ n2 ...

  7. C++ int与string的互转

    int本身也要用一串字符表示,前后没有双引号,告诉编译器把它当作一个数解释.缺省情况下,是当成10进制(dec)来解释,如果想用8进制,16进制,怎么办?加上前缀,告诉编译器按照不同进制去解释.8进制 ...

  8. TYVJ1340 送礼物

    P1340 送礼物 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后 ...

  9. 外贸电子商务网站之Prestashop修改顶部导航

    如修改以上所示顶部导航. 如何在prestashop顶部导航栏添加链接,Module>Top horizontal menu点击进入Configure页面 1,在Settings 中看到 链接 ...

  10. StatusBar用法

    一.StatusBar组件介绍 StatusBar 是 React Native 0.20 起新增的跨平台组件,它可以用来设置并动态改变设备的状态栏显示特性. StatusBar 组件可以同时加载多个 ...