最短路

题意:有一栋楼100层,从0到99编号层数,有多部电梯(最多5部),给出每部每部电梯的速度,即上或下一层楼所用的秒数。然后每部电梯不一定在所有楼层出现,给你所有电梯可能出现的层数。给你一个目标层,要你从0层开始到目标层,问所用时间最短。在0层的时候选择做哪步电梯出发不需要时间的,但是在中间的楼层,想换电梯的时候,需要60秒

这个题目看完就可以想到是最短路,每层楼是1个顶点,一共100个点,然后对于楼层而言可以通过电梯到达的话就是有一条边,权值就是时间,那么可能出现平行边,比如1号电梯可以从10楼到20楼,用时200秒,2号电梯也可以从10到20楼用时100秒……………………

这题,一开始没想那么多,用了邻接表来建图做,然后sample不过,然后调试一下发现了转换电梯的时候会出错,然后思考了很久不知道怎么搞

一般的最短路其实都基于一个性质就是都符合最优子结构的,但是这道题其实不符合最优子结构,因为轮换增加的60秒破坏了最优子结构,看sample1的数据就可以知道,从0到30楼是要经过15楼的,但是去15的时候却不是最短的,我们是用2号电梯到达15楼,但是如果要去15楼的时间最短那么应该是坐1号电梯,但是如果坐了1号电梯到15楼将无法满足到30楼的时间最短,这其实有种为了最后的目标的最优解而舍近求远的感觉

后来想了一下,想了其实用邻接表来建图本身就是一个失败的旋转,如果是用邻接矩阵来建图,那么整个问题就变得很简单

所以这个题目让我想到师兄之前说的一句话,做图论讲究经验,尤其是什么问题有什么来建图这个很关键,这次算是体会到了

我写了3个版本,第一个普通的dij+邻接矩阵 , 第二个spfa+邻接矩阵 , 第三个优先队列dij+邻接矩阵

3个版本只是改了求最短路的函数,读取数据和建图函数是一样,都是邻接矩阵建图

至于为什么这样建图很难文字描述,可以仔细看第一份代码的建图(后面的建图是一样的),看代码反而更容易懂

然后要AC还要注意三点

1.终点楼层可能就是0层,所以要特殊判断,输出0。

2.三个代码中都是算多了一个60秒,就是从0层出发的时候算多一个60秒,但是题目说不用的,所以最后答案减去1个60

3.三个代码松弛都是 d[u]+g[u][v]+60 < d[v]  ,  并不是说换不换电梯都加60,而是在换电梯的时候才+60,为什么呢,看懂了建图部分这个就懂了

第一个普通的dij+邻接矩阵

#include <cstdio>
#include <cstring>
#define N 110
#define INF 0x3f3f3f3f
int g[N][N],d[N],sp[10];
int s,t,n;void graph(int k,int ccount , int *m)
{for(int i=1; i<=ccount; i++)for(int j=i+1; j<=ccount; j++){int u=m[i],v=m[j],w=(v-u)*sp[k];if(w<g[u][v])g[u][v]=g[v][u]=w;}return ;
}
void input()
{int m[N],ccount;  char ch;memset(g,0x3f,sizeof(g));for(int i=1; i<=n; i++) scanf("%d",&sp[i]);for(int i=1; i<=n; i++){ccount=0;while(1){scanf("%d",&m[++ccount]);ch=getchar();if(ch=='\n')break;}//for(int j=1; j<=ccount; j++)//printf("%d ",m[j]);//printf("\n");graph(i,ccount,m);  //邻接矩阵建图
    }return ;
}
void dij()
{int fin[N];memset(d,0x3f,sizeof(d));memset(fin,0,sizeof(fin));d[s=0]=0;for(int nn=0; nn<99; nn++)  //进行n-1次
    {int min=INF,u=s,flag=0;for(int i=0; i<=99; i++)if(!fin[i] && d[i]<min){ min=d[i]; u=i; flag=1; }if(!flag) break;  //已经找不到了即结束了fin[u]=1;for(int v=0; v<=99; v++)  //松弛if(!fin[v] && d[u]+g[u][v]+60 < d[v])d[v]=d[u]+g[u][v]+60;}if(d[t]==INF)printf("IMPOSSIBLE\n");else if(t==s)printf("0\n");elseprintf("%d\n",d[t]-60);
}
int main()
{while(scanf("%d%d",&n,&t)!=EOF){input();dij();  //dij邻接矩阵
    }return 0;
}

 第二个spfa+邻接矩阵

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 110
#define INF 0x3f3f3f3f
int g[N][N],d[N],sp[10];
int s,t,n;void graph(int k,int ccount , int *m)
{for(int i=1; i<=ccount; i++)for(int j=i+1; j<=ccount; j++){int u=m[i],v=m[j],w=(v-u)*sp[k];if(w<g[u][v])g[u][v]=g[v][u]=w;}return ;
}
void input()
{int m[N],ccount;  char ch;memset(g,0x3f,sizeof(g));for(int i=1; i<=n; i++) scanf("%d",&sp[i]);for(int i=1; i<=n; i++){ccount=0;while(1){scanf("%d",&m[++ccount]);ch=getchar();if(ch=='\n')break;}//for(int j=1; j<=ccount; j++)//printf("%d ",m[j]);//printf("\n");graph(i,ccount,m);  //邻接矩阵建图}return ;
}void spfa()
{queue<int> q;int vis[N];memset(vis,0,sizeof(vis));memset(d,0x3f,sizeof(d));d[s=0]=0; vis[s]=1;q.push(s);while(!q.empty()){int u=q.front(); vis[u]=0; q.pop();for(int v=0; v<=99; v++)if(d[u]+g[u][v]+60 < d[v]){d[v]=d[u]+g[u][v]+60;if(!vis[v]){q.push(v);vis[v]=1;}}}if(d[t]==INF)printf("IMPOSSIBLE\n");else if(t==s)printf("0\n");elseprintf("%d\n",d[t]-60);}
int main()
{while(scanf("%d%d",&n,&t)!=EOF){input();spfa();}return 0;
}

第三个优先队列dij+邻接矩阵

#include <cstdio>
#include <cstring>
#include <queue>
#include <utility>
#include <vector>
using namespace std;
#define N 110
#define INF 0x3f3f3f3f
int g[N][N],d[N],sp[10];
int s,t,n;
typedef pair<int , int> pii;void graph(int k,int ccount , int *m)
{for(int i=1; i<=ccount; i++)for(int j=i+1; j<=ccount; j++){int u=m[i],v=m[j],w=(v-u)*sp[k];if(w<g[u][v])g[u][v]=g[v][u]=w;}return ;
}
void input()
{int m[N],ccount;  char ch;memset(g,0x3f,sizeof(g));for(int i=1; i<=n; i++) scanf("%d",&sp[i]);for(int i=1; i<=n; i++){ccount=0;while(1){scanf("%d",&m[++ccount]);ch=getchar();if(ch=='\n')break;}//for(int j=1; j<=ccount; j++)//printf("%d ",m[j]);//printf("\n");graph(i,ccount,m);  //邻接矩阵建图}return ;
}void dij()
{priority_queue<pii,vector<pii>,greater<pii> > q; //优先队列3个参数,变量类型,容器类型,比较算子int fin[N];memset(fin,0,sizeof(fin));memset(d,0x3f,sizeof(d));d[s=0]=0;q.push(make_pair(d[s],s));while(!q.empty()){pii p; int u;p=q.top(); q.pop();u=p.second;  //点的标号if(fin[u]) continue;  //该点已经计算过fin[u]=1;  for(int v=0; v<=99; v++)  //松弛if( d[u]+g[u][v]+60 < d[v] ){d[v]=d[u]+g[u][v]+60;q.push(make_pair(d[v],v));}}if(d[t]==INF)printf("IMPOSSIBLE\n");else if(t==s)printf("0\n");elseprintf("%d\n",d[t]-60);
}int main()
{while(scanf("%d%d",&n,&t)!=EOF){input();dij();  //dij优先队列}return 0;
}

uva 10801 Lift Hopping相关推荐

  1. uva 10801 - Lift Hopping(最短路Dijkstra)

    1 /* 2 题目大意: 3 就是一幢大厦中有0-99的楼层, 然后有1-5个电梯!每个电梯有一定的上升或下降速度和楼层的停止的位置! 4 问从第0层楼到第k层最少经过多长时间到达! 5 6 思路:明 ...

  2. UVA 10801 Lift Hopping(最短路)

    思路:以每一层楼为顶点,每个电梯可以到达的两层楼之间的秒数为每一条边的权值,以此构建一个无向图.然后利用dijkstra求出最短的时间,注意每次换乘电梯需要等待60s(因为同一个电梯上的楼层是相互可达 ...

  3. H - Lift Hopping UVA - 10801

    1.题目 H - Lift Hopping UVA - 10801 A skyscraper has no more than 100 floors, numbered from 0 to 99. I ...

  4. UVA 821 Page Hopping

    Floyd水题 #include<cstdio> #include<iostream> using namespace std; int N; const int MAXN=1 ...

  5. Uva 10801 最短路,搜索

    A skyscraper has no more than 100 floors, numbered from 0 to 99. It has n (1 ≤ n ≤ 5) elevatorswhich ...

  6. oracle安装后开机很慢,Windows下安装Oracle拖慢开机速度的解决方法

    环境:win7 + oracle R2 方法:将安装Oracle后自动开机启动的服务改为手动启动 步骤如下: 1.修改服务项 Ctrl + R,输入services.msc,打开服务列表,找到Orac ...

  7. 紫书《算法竞赛入门经典》

    紫书<算法竞赛入门经典>题目一览 第3章 数组和字符串(例题) UVA 272 TEX Quotes UVA 10082 WERTYU UVA 401 Palindromes UVA 34 ...

  8. 提取了下刘汝佳推荐的题号...

    今天闲来没事上uva oj提取了下刘汝佳推荐的acm题号,原始数据如下: Volume 0. Getting Started    10055 - Hashmat the Brave Warrior ...

  9. 初学者acm的练习题指南

    上机练习题参考题 忘了在哪找的啦~~希望对大家有帮助呦 <!--[if !supportLists]-->1.    <!--[endif]-->Programming Bas ...

最新文章

  1. django学习笔记【003】创建第一个带有model的app
  2. Java开发面试技巧,如何设计一个优雅的RESTFUL的接口
  3. MongoDB GridFS——本质上是将一个文件分割为大小为256KB的chunks 每个chunk里会放md5标识 取文件的时候会将这些chunks合并为一个整体返回...
  4. 别傻了,年轻人买“养生奶茶”才不是为了养生!
  5. ITK:轮廓空间对象
  6. GitHub上README.md教程(copy)
  7. 三星Galaxy S21系列通过认证:终究还是要学苹果“保护环境”?
  8. [Twisted] Protocols协议和Protocol Factories 协议工厂
  9. SQL SERVER 2012 执行计划走嵌套循环导致性能问题的案例
  10. 大数据技术的特点有哪些
  11. 为什么要用非关系型数据库nosql
  12. 响应式编程、反应式编程的简易教程-超赞演讲
  13. 手把手搭建一个完整的javaweb项目(适合新手)
  14. Java 封装、继承、多态的理解
  15. CSS-div垂直居中方法总结
  16. ERP系统如何操作?具体操作步骤是什么?
  17. 基于搜狐新闻数据【完整版】训练中文word2vec模型
  18. STM32_iC-MHM磁编码器使用
  19. 热门编程语言那么多,该选择哪个
  20. 泛函分析笔记(二十一) 障碍问题

热门文章

  1. 构建良好的敏捷团队氛围
  2. c++中使用 数据库相关知识点 部分后面慢慢加
  3. linux的gromacs模拟分子运动,分子动力学技术交流---gromacsamber
  4. 案例 | 新零售如何精细化运营?百联全渠道经验谈
  5. 周五话运营 | 和用户谈一段不分手的恋爱(留存分析)
  6. 几款xshell绝佳配色方案
  7. 使用Opencv构建一个简单的图像相似检测器(MSE、SSIM)
  8. halcon算子之tuple_gen_const,用于生成特定长度的元组并且初始化其元素
  9. consul 1.2 支持service mesh
  10. vue Iframe