题意:给了图,以及s和t,让你求s到t花费的最短路程、最短时间,以及输出对应的路径。

     对于最短路程,如果路程一样,输出时间最少的。

   对于最短时间,如果时间一样,输出节点数最少的。

     如果最短路程和最短时间路径一样,合并输出一次即可。

纯粹就是练习dijkstra,没什么难的。

第一次dijkstra求最短路程,记录下每个节点的路程和时间。

第二次dijkstra求最短时间,记录下每个节点的时间和经过的节点数。

pre数组用来存储前驱节点,保存路径

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std; const int maxn=;
int n,m;
int dis[maxn];
int distime[maxn];
int nums[maxn];
int pre[maxn];
int vis[maxn];
struct Edge{
int w,time;
}edge[maxn][maxn];
struct disNode{
int dis; //统计距离
int time; //统计时间
int u;
bool operator<(const disNode tmp)const{
if(dis==tmp.dis)
return time>tmp.time;
else
return dis>tmp.dis;
}
}; struct timeNode{
int time; //统计时间
int nums; //统计路径的节点数
int u;
bool operator<(const timeNode tmp)const{
if(time==tmp.time)
return nums>tmp.nums;
else
return time>tmp.time;
}
};
/*
求取最短路径,如果最短距离一样,取时间花费最小的
*/
void dijkstraDis(int s){
int u;
for(int i=;i<n;i++){
dis[i]=INF;
vis[i]=;
pre[i]=-;
}
priority_queue<disNode>q;
disNode node;
node.u=s;
node.dis=dis[s]=;
node.time=dis[s]=;
q.push(node);
while(!q.empty()){
node=q.top();
q.pop();
u=node.u;
vis[u]=;
for(int v=;v<n;v++){
if(!vis[v] && edge[u][v].w!=-){
//一开始都只判断了前一个,没判断后面一个。。。导致有个样例没过
if((dis[u]+edge[u][v].w<dis[v])||(dis[u]+edge[u][v].w==dis[v] && distime[u]+edge[u][v].time<distime[v])){
dis[v]=dis[u]+edge[u][v].w;
distime[v]=distime[u]+edge[u][v].time;
node.dis=dis[v];
node.time=distime[v];
node.u=v;
pre[v]=u;
q.push(node);
}
}
}
}
}
/*
求取时间最小的,如果时间一样,取路径节点数最小的。
*/
void dijkstraTime(int s){
int u;
for(int i=;i<n;i++){
distime[i]=INF;
vis[i]=;
pre[i]=-;
nums[i]=;
}
priority_queue<timeNode>q;
timeNode node;
node.u=s;
node.time=distime[s]=;
node.nums=nums[s]=;
q.push(node);
while(!q.empty()){
node=q.top();
q.pop();
u=node.u;
vis[u]=;
for(int v=;v<n;v++){
if(!vis[v] && edge[u][v].w!=-){
if((distime[u]+edge[u][v].time<distime[v])||(distime[u]+edge[u][v].time==distime[v] && nums[u]+<nums[v])){
distime[v]=distime[u]+edge[u][v].time;
nums[v]=nums[u]+;
node.time=distime[v];
node.nums=nums[v];
node.u=v;
pre[v]=u;
q.push(node);
}
}
}
}
} int main()
{
int v1,v2,a,b,c;
int s,t;
scanf("%d %d",&n,&m);
for(int i=;i<n;i++){
for(int j=;j<n;j++){
edge[i][j].w=-;
}
}
for(int i=;i<m;i++){
scanf("%d %d %d %d %d",&v1,&v2,&a,&b,&c);
edge[v1][v2].w=b;
edge[v1][v2].time=c;
if(a==){
edge[v2][v1].w=b;
edge[v2][v1].time=c;
}
}
scanf("%d %d",&s,&t);
dijkstraDis(s);
int disAns=dis[t];
int disPath[n+];
int disCnt=;
//最短路径
int u=t;
disPath[disCnt]=u;
disCnt++;
while(pre[u]!=-){
disPath[disCnt]=pre[u];
u=pre[u];
disCnt++;
} dijkstraTime(s);
int timeAns=distime[t];
int timePath[n+];
int timeCnt=;
//最短时间路径
u=t;
timePath[timeCnt]=u;
timeCnt++;
while(pre[u]!=-){
timePath[timeCnt]=pre[u];
u=pre[u];
timeCnt++;
} bool isSame=true;
if(disCnt==timeCnt){
for(int i=;i<disCnt;i++){
if(disPath[i]!=timePath[i]){
isSame=false;
break;
}
}
}
else
isSame=false; if(isSame){
printf("Distance = %d; Time = %d: %d",disAns,timeAns,s);
for(int i=disCnt-;i>=;i--){
printf(" -> %d",disPath[i]);
}
}
else{
printf("Distance = %d: %d",disAns,s);
for(int i=disCnt-;i>=;i--){
printf(" -> %d",disPath[i]);
}
printf("\n");
printf("Time = %d: %d",timeAns,s);
for(int i=timeCnt-;i>=;i--){
printf(" -> %d",timePath[i]);
}
} return ;
}

PAT甲题题解-1111. Online Map (30)-PAT甲级真题(模板题,两次Dijkstra,同时记下最短路径)的更多相关文章

  1. PAT甲题题解-1107. Social Clusters (30)-PAT甲级真题(并查集)

    题意:有n个人,每个人有k个爱好,如果两个人有某个爱好相同,他们就处于同一个集合.问总共有多少个集合,以及每个集合有多少人,并按从大到小输出. 很明显,采用并查集.vis[k]标记爱好k第一次出现的人 ...

  2. PAT甲题题解-1114. Family Property (25)-(并查集模板题)

    题意:给出每个人的家庭成员信息和自己的房产个数与房产总面积,让你统计出每个家庭的人口数.人均房产个数和人均房产面积.第一行输出家庭个数,随后每行输出家庭成员的最小编号.家庭人口数.人均房产个数.人均房 ...

  3. PAT甲题题解-1030. Travel Plan (30)-最短路+输出路径

    模板题最短路+输出路径如果最短路不唯一,输出cost最小的 #include <iostream> #include <cstdio> #include <algorit ...

  4. PAT甲级题解-1066. Root of AVL Tree (25)-AVL树模板题

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6803291.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  5. PAT甲题题解-1022. Digital Library (30)-map映射+vector

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789235.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  6. PAT甲题题解-1103. Integer Factorization (30)-(dfs)

    该题还不错~. 题意:给定N.K.P,使得可以分解成N = n1^P + … nk^P的形式,如果可以,输出sum(ni)最大的划分,如果sum一样,输出序列较大的那个.否则输出Impossible. ...

  7. PAT甲题题解-1004. Counting Leaves (30)-统计每层叶子节点个数+dfs

    统计每层的叶子节点个数建树,然后dfs即可 #include <iostream> #include <cstdio> #include <algorithm> # ...

  8. PAT甲题题解-1072. Gas Station (30)-dijkstra最短路

    题意:从m个加油站里面选取1个站点,使得其离住宅的最近距离mindis尽可能地远,并且离所有住宅的距离都在服务范围ds之内.如果有很多相同mindis的加油站,输出距所有住宅平均距离最小的那个.如果平 ...

  9. PAT甲题题解-1091. Acute Stroke (30)-BFS

    题意:给定三维数组,0表示正常,1表示有肿瘤块,肿瘤块的区域>=t才算是肿瘤,求所有肿瘤块的体积和 这道题一开始就想到了dfs或者bfs,但当时看数据量挺大的,以为会导致栈溢出,所以并没有立刻写 ...

随机推荐

  1. 拉格朗日插值和牛顿插值 matlab

    1. 已知函数在下列各点的值为   0.2 0.4 0.6 0.8 1.0   0.98 0.92 0.81 0.64 0.38 用插值法对数据进行拟合,要求给出Lagrange插值多项式和Newto ...

  2. Oracle Spatial中SDO_Geometry说明

    Oracle Spatial中SDO_Geometry说明 在ArcGIS中通过SDE存储空间数据到Oracle中有多种存储方式,分别有:二进制Long Raw .ESRI的ST_Geometry以及 ...

  3. Java应用中的编码问题(转载)

    第三篇:JAVA字符编码系列三:Java应用中的编码问题这部分采用重用机制,引用一篇文章来完整本部分目标.来源:  Eceel东西在线 问题研究--字符集编码 地址:http://china.ecee ...

  4. day2-作业及答案

    作业:第一组: 1.接收用户输入一个年份,判断是否是闰年(判断闰年的方法是该年能被4整除并且不能被100整除,或者是可以被400整除) 2.接收用户输入一组整数,输入负数时结束输入,输出这组数字的和: ...

  5. <数据结构与算法分析>读书笔记--利用Java5泛型实现泛型构件

    一.简单的泛型类和接口 当指定一个泛型类时,类的声明则包括一个或多个类型参数,这些参数被放入在类名后面的一对尖括号内. 示例一: package cn.generic.example; public ...

  6. redis集群遇到的坑

    [root@insure src]# ./redis-cli -c -h 172.16.*.* -p 6370 输入密码: auth 密码 查看节点信息 172.16.*.*:6370> clu ...

  7. Ubuntu 中使用git 上传代码

    现在很多人都愿意把自己的代码分享给大家,所以有很多的代码管理的软件 ,比如SVN Git 等软件.今天就讲一下  git 的简单的应用,上传代码.用 git 上传代码 要有个git 账号,这是必不少的 ...

  8. Arduino入门笔记(9):蓝牙模块及第一辆蓝牙遥控小车

    转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 欢迎加入讨论群 64770604 一.本次实验所需器材 1.Arduino UNO板 https://item.t ...

  9. linux iostat 性能指标说明(转)

    iostat属于sysstat软件包.可以用yum install sysstat 直接安装. 备注: 如果%iowait的值过高,表示硬盘存在I/O瓶颈, %idle值高,表示CPU较空闲, 如果% ...

  10. day72

    今日内容: 1 创建多表模型(详情见代码) from django.db import models # Create your models here. class Publish(models.M ...