2. 旅行计划

★★   输入文件:djs.in   输出文件:djs.out   简单对比
时间限制:3 s   内存限制:128 MB

【题目描述】

过暑假了,阿杜准备出行旅游,他已经查到了某些城市的两两之间的距离及可行路线(可行路线有方向),如下图所示。请你编程计算从阿杜所住城市到其它城市的最短路径以帮助阿杜制定旅行计划。

【输入格式】

输入由若干行组成,第一行有三个整数 n(1≤n≤100) 为城市数,m(1≤m≤n2) 为城市间道路数,s(0≤s≤n−1) 是阿杜所住城市。第 2 至 m+1 行是每条路的信息,每行三个整数,为道路的起点、终点和两城市间距离。(城市从 0 开始编号)

【输出格式】

输出 n 组(按城市编号由小至大),每组三行

第一行:城市编号及一个冒号

第二行:path及一个冒号,后面是最短路径节点编号序列(编号间用一个空格隔开)

第三行:cost及一个冒号,后面是一个整数,表示路径距离

如果没有通路则输出 no

【输入样例】

6 8 0
0 2 10
0 4 30
0 5 100
1 2 5
2 3 50
3 5 10
4 3 20
4 5 60

【输出样例】

0:
no
1:
no
2:
path:0 2
cost:10
3:
path:0 4 3
cost:50
4:
path:0 4
cost:30
5:
path:0 4 3 5
cost:60

自动选择评测机
 
gcc/g++4.8.5
gcc/g++4.8.5 -O2
gcc/g++4.8.5(C++11)
gcc/g++4.6.3
gcc/g++4.6.3 -O2

提交代码 Pascal C C++

看到评论区的一群大佬的评论 我立刻不淡定了  决定来瞅瞅(探头探脑   这一道据说很坑的题 没想到想了3分钟 敲了4分钟 完美AC!

那么这一道题到底应该咋做

我的时间复杂度是(mlogm  +  n^2)n<100  m<10000  这个时间复杂度看起来还是 很棒的

首先很简单 我们要来按照题目中给出的单向边和起点 跑一遍dijkstra  这是O(n)的

然后重点在于怎样输出路径

在之前的时候总是看到别人的代码里有一个非常神奇的数组是path  然而我并没有学过这么难的东西(俺可是初学者--哈哈)

首先我们最暴力的想法肯定是O(n^3)的

对于每一个点 从剩下的点里面 看一下哪一个点是他的前驱

很显然这一道题n^3也没啥问题

但是蒟蒻拒绝!

所以我们想办法压缩到O(n^2)

听起来不错

既然我们浪费时间主要在找前驱  那么我们只需要在dijkstra的过程中顺便用一个pathpre数组来存每一个点的前驱  后面直接跑一个递归调用一下下就好啦

具体看代码 还是非常好理解的优化(这是蒟蒻自己发明的!请求专利)

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define pa pair<int,int>
#define maxn 115
using namespace std;
int n,m,s;
int dis[maxn],vis[maxn],pathpre[maxn];
vector<int> v[maxn],w[maxn];
priority_queue< pa,vector<pa>,greater<pa> > q;
inline int read()
{
int X=; bool flag=; char ch=getchar();
while(ch<''||ch>'') {if(ch=='-') flag=; ch=getchar();}
while(ch>=''&&ch<='') {X=(X<<)+(X<<)+ch-''; ch=getchar();}
if(flag) return X;
return ~(X-);
}
inline void write(int X)
{
if(X<) {X=~(X-); putchar('-');}
if(X>) write(X/);
putchar(X%+'');
}
void Dijkstra()
{
memset(dis,0x3f,sizeof(dis));
dis[s]=;
q.push(make_pair(,s));
while(!q.empty()){
int rt=q.top().second;
q.pop();
if(vis[rt]) continue;
vis[rt]=;
for(int i=;i<v[rt].size();i++){
int to=v[rt][i];
if(dis[to]>dis[rt]+w[rt][i]){
dis[to]=dis[rt]+w[rt][i];
pathpre[to]=rt;
q.push(make_pair(dis[to],to));
}
}
}
}
bool flagfinish=false;
void path_out(int rt){//最差时间复杂度:O(mlogm+n^2)
if(rt==s){
write(rt);printf(" ");
flagfinish=true;
return;
}
// for(int i=0;i<v[rt].size();i++)
// if(dis[v[rt][i]]==dis[rt]+w[rt][i]){ 错
// path_out(v[rt][i]);
// write(rt);printf(" ");
// return;
// }
path_out(pathpre[rt]);write(rt);printf(" ");
}
int main()
{
freopen("djs.in","r",stdin);
freopen("djs.out","w",stdout);
n=read(),m=read(),s=read();
for(int i=,x,y,z;i<=m;i++)
{
x=read(),y=read(),z=read();
v[x].push_back(y);w[x].push_back(z);
}
Dijkstra();
for(int i=;i<n;i++)
{
write(i);puts(":");
if(dis[i]==inf||i==s) puts("no");
else
{
printf("path:");path_out(i);printf("\n");
printf("cost:%d\n",dis[i]);flagfinish=false;
}
}
return ;
}

cogs 2. 旅行计划 dijkstra+打印路径小技巧的更多相关文章

  1. COGS 2. 旅行计划

    2. 旅行计划 ★☆   输入文件:djs.in   输出文件:djs.out   简单对比时间限制:3 s   内存限制:128 MB 过暑假了,阿杜准备出行旅游,他已经查到了某些城市的两两之间的距 ...

  2. 紧急救援 L2-001 dijkstra 打印路径 最短路条数 权值

    较为复杂的dijkstra 包含路径打印  最小路的条数  最小路径的情况下取最大权值 v0要是标记就会出错...? 有权值的题目  不能设置mp[i][i]为0  否则会无限加权 这题很有参考价值 ...

  3. 一个人的旅行(用小技巧转化为dijkstra算法)

    注意: 1:因为两点之间可能有多条路,所以更新路径长度的时候做一次判断 if(time < mat[a][b]) mat[a][b] = mat[b][a] = time; 2:因为主函数中的数 ...

  4. L2-001. 紧急救援 (Dijkstra算法打印路径)

    作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求 ...

  5. 牛客-小a的旅行计划 + 数学推导

    小a的旅行计划 题意: 小a终于放假了,它想在假期中去一些地方游玩,现在有N个景点,编号为,同时小b也想出去游玩.由于一些特殊♂原因,他们的旅行计划必须满足一些条件 首先,他们可以从这N个景点中任意选 ...

  6. 牛客ACM赛 B [小a的旅行计划 ]

    链接 B 小a的旅行计划 把\(n\)个数中选任意数分成\(a,b\)两个集合,集合无区别,要求不包含且有交,求方案数.\(n\leq 10^{13}\) 首先讨论\(a,b\)并集是否为全集: 若是 ...

  7. 【51Nod】1273 旅行计划 树上贪心

    [题目]51Nod 1273 旅行计划 [题意]给定n个点的树和出发点k,要求每次选择一个目的地旅行后返回,使得路径上未访问过的点最多(相同取编号最小),旅行后路径上所有点视为访问过,求旅行方案.\( ...

  8. 51nod 1273 旅行计划——思维题

    某个国家有N个城市,编号0 至 N-1,他们之间用N - 1条道路连接,道路是双向行驶的,沿着道路你可以到达任何一个城市.你有一个旅行计划,这个计划是从编号K的城市出发,每天到达一个你没有去过的城市, ...

  9. 51nod-1273: 旅行计划

    [传送门:51nod-1273] 简要题意: 给出一棵树,点数为n,现在你有一个旅行计划,从k城市出发,每天前往一个没去过的城市,并且旅途中经过的没有去过的城市尽可能的多(如果有2条路线,经过的没有去 ...

随机推荐

  1. HDU 2601

    题意:给出一个n求出n=i*j+i+j共有几种组合,i,j>0. 开始挺傻的.没想到化成因式的乘积.- - . 思路:i*j+i+j=(i+1)*(j+1)=n+1 #include<io ...

  2. Mockito 使用

    1. 算术测试类 package com.smart.test.mockito; public interface Calculator { public int add(int a, int b); ...

  3. 如何在 centos 7.3 上安装 caffe 深度学习工具

    有好多朋友在安装 caffe 时遇到不少问题.(看文章的朋友希望关心一下我的创业项目趣智思成) 今天测试并整理一下安装过程.我是在阿里云上测试,选择centos 7.3 镜像. 先安装 epel 源 ...

  4. NuGet 符号服务器

    在新的 VisualStudio 支持使用 NuGet 符号服务器,可以支持新的 Portable PDB 调试符号的库,本文告诉大家如何打包上传带符号的库和使用符号服务器 在 2018 的 11 月 ...

  5. JMETER+JENKINS接口测试持续集成

    FIDDER+ANT+JENKINS+JMETER+SVN+tomcat接口测试集成 操作流程: 1.测试人员通过FIDDER过滤抓取接口调用信息,导出成jmx文件.(jmeter支持命令行方式调用j ...

  6. Linux 内核驱动结构嵌入

    如同大部分驱动核心结构的情形, device_driver 结构常常被发现嵌到一个更高级的, 总 线特定的结构. lddbus 子系统不会和这样的趋势相反, 因此它已定义了它自己的 ldd_drive ...

  7. Linux 内核取消 urb

    为停止一个已经提交给 USB 核心的 urb, 函数 usb_kill_urb 或者 usb_unlink_urb 应 当被调用: int usb_kill_urb(struct urb *urb); ...

  8. 两种方法,轻松上手ConfigMap!

    属性配置文件在任何应用程序中都非常重要.它们不仅可以让应用程序具备灵活性,还能够根据文件中配置的值产生不同的功能.实际上,在staging.开发.测试.UAT或生产环境中,我们都使用属性配置文件来驱动 ...

  9. 如何更优雅地对接第三方API

    本文所有示例完整代码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/third 我们在日常开发过程 ...

  10. 开包即食的教程带你浅尝最新开源的C# Web引擎 Blazor

    在今年年初, 恰逢新春佳节临近的时候. 微软给全球的C#开发者们, 着实的送上了一分惊喜. 微软正式开源Blazor ,将.NET带回到浏览器. 这个小惊喜, 迅速的在dotnet开发者中间传开了. ...