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. java 集合类 & 容器

    为什么出现集合类? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就要对对象进行存储,集合就是存储对象最常用的一种方式. 数组和集合类同是容器,有何不同? 数组虽然也可以存储 ...

  2. Intellij Idea更换主题

    <h1 class="title">Intellij Idea更换主题</h1> <!-- 作者区域 --> <div class=&qu ...

  3. java throw

    自行抛出一个异常对象,抛出异常类的对象: 若throw抛出的是Runtime异常: 程序可以显示使用try...catch来捕获并处理,也可以不管,直接交给方法调用者处理: 若throw抛出Check ...

  4. 【t085】Sramoc问题

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] Sramoc(K,M)表示用数字0,1,2,...,K-1组成的自然数中能被M整除的最小数.给定K,M ...

  5. js求1到任意数之间的所有质数

    何为质数: 只能被1 和 自身 整除的数; 方法: 利用js中求模, 看是否有余数. ---> 3%2 = 1; 5%2 = 3......... 代码如下: function test (n) ...

  6. C# 获取 PC 序列号

    在 C++ 需要使用 GetSystemFirmwareTable 的方法来获得 PC 的序列号,需要写的代码很多,但是在 C# 可以使用 WMI 来拿到序列号 首先是安装 System.Manage ...

  7. CodeForces - 922D Robot Vacuum Cleaner (贪心)

    Pushok the dog has been chasing Imp for a few hours already. Fortunately, Imp knows that Pushok is a ...

  8. pandas小程序应用-实验

    背景:来自于日常工作,针对医院行政人员统计日常门诊信息,手工统计繁琐.容易出错的问题,结合实际特点,采用python对数据进行自动统计. 具体步骤如下: 1.引入python工具包. import p ...

  9. C# struct和class

    文字说明 值类型,存储于堆栈,存在于计算机内存逻辑区域中 引用类型,存储在堆中,位于计算机的不同逻辑位置 struct是值类型 推荐较小的数据类型使用,因为结构的大小会影响应用程序的性能 修改实际上是 ...

  10. (1)51单片机NOP指令

    提问:什么是NOP指令?干什么用的?单片机程序里执行一条nop指令需要多长时间? (1)一个NOP就是一个机器周期 (2)空指令,延时一个机器周期 (3)这个与单片机型号.指令类型和使用的晶振频率有关 ...