题意:

给定一个带权无向图,每条边的代价为边权/当前速度,每次到达一个新节点,速度都会除以10。

求0号点到n-1号点的最小代价,如果多解输出点数最少的解,输出代价、路径点数、路径经过的点。

1<=边数<=10^5, 1<=点数<=10^5, 0<=边权<=9

题解:

比较有趣的一道题…难度不算太高,但一些地方比较容易想错…

这题的边代价可变本身并不是什么大问题,因为是图中所有边一起变大,

但是一开始就会遇到一个问题,就是总代价数字过大,没有办法直接存储和比较。

观察到边权的奇怪的条件,就会发现代价其实就是经过的边权拼起来的十进制数。

那么就有办法进行比较了。

对于任意两条到底终点的路径,如果没有前导零,一定是短的优于长的。

所以可以用BFS来处理。

首先为了排除前导零,从终点开始只走权值为0的边来BFS,求出每个可以无代价到达终点的点的路径。

然后从起点开始进行BFS。这个地方最容易错。

BFS时一般只知道和当前点直接相连的点和边的信息,所以可以先考虑理想情况,

即起点到当前点和目标点经过的路径中除了当前目标点以外的代价是相同的。

这时只需比较当前边的权是否小于目标点的代价中的最高位即可。

还有一种比较容易处理的情况是当前点的路径长度已经大于目标点路径,那么不更新。

然后还有一种情况就是当前点路径长度小于目标点,

因为是BFS,所以只有首次访问目标点时出现。(初始化为无穷大)

剩下的一种情况就是前面说的理想情况的一般化,不能保证之前的路径代价相同。

出于时间复杂度考虑,暴力比较之前的路径是不妥的。

但是我们可以想到一种利用顺序的策略,BFS是逐层搜索,

那么如果每一层都按照当前层的代价从小到大搜索,

那么每搜索到一个点,都会是到这个点(除这层的代价外)最小的代价。

所以后面的点如果当前层代价一样(原本是需要麻烦的比较的情况)就不会更新这个点的状态,

如果当前层代价小就会更新这个状态(高位的优先度高),

所以这种麻烦的情况就不存在了。

实现的话可以开一个滚动的桶,桶里装一个包含某层代价为x的点的队列,从小到大处理即可。

时间复杂度O(n)

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <cstdio>
#include <cstring>
#include <queue>
#include <utility>
using namespace std;
inline int read()
{
int s = ; char c; while((c=getchar())<'0'||c>'9');
do{s=s*+c-'0';}while((c=getchar())>='0'&&c<='9');
return s;
}
const int N = ;
int n,m,tot,s[N],l[N],l0[N],fr0[N],fr[N],h[N],ans[N],ansp;
struct eg{int dt,w,nx;}e[N*];
queue<int> q,qa[][];
bool inq[N],inq0[N],z[N];
void link(int aa,int bb,int ww)
{
e[++tot].nx = h[aa]; e[tot].dt = bb; e[tot].w = ww; h[aa] = tot;
e[++tot].nx = h[bb]; e[tot].dt = aa; e[tot].w = ww; h[bb] = tot;
}
void zerobfs()
{
q.push(n-); fr0[n-] = -; inq0[n-] = ;
while(!q.empty())
{
int hn = q.front(); q.pop();
for(int nx,pt=h[hn];pt;pt=e[pt].nx)
if(!e[pt].w&&!inq0[nx=e[pt].dt])
q.push(nx), inq0[nx] = , fr0[nx] = hn, l0[nx] = l0[hn]+;
}
}
void bfs()
{
qa[][].push();
memset(s,0x7f,sizeof s); memset(l,0x7f,sizeof l);
s[] = ; l[] = ; fr[] = -; z[] = ;
int curp = ;
while()
{
curp ^= ;
while(!q.empty())
{
int hn = q.front(); q.pop();
if(!inq[hn]) qa[curp][s[hn]].push(hn), inq[hn] = ;
}
bool flag = ;
for(int i=;i<=;i++)
{
while(!qa[curp][i].empty())
{
int hn = qa[curp][i].front(); qa[curp][i].pop(); flag = ;
for(int nx,pt=h[hn];pt;pt=e[pt].nx)
{
nx = e[pt].dt;
if(l[hn]+<l[nx]||(l[hn]+==l[nx]&&(e[pt].w<s[nx])))
{
s[nx] = e[pt].w, l[nx] = l[hn]+, fr[nx] = hn;
if(!inq[nx]) q.push(nx);
}
}
}
}
if(flag) break;
}
}
int main()
{
int i,j=;
n = read(); m = read();
for(i=;i<=m;i++){ int aa = read(), bb = read(); link(aa,bb,read()); }
zerobfs(); bfs();
ansp = n-;
for(i=;i<n;i++) if(inq0[i])
if(l[i]<l[ansp]||(l[i]==l[ansp]&&s[i]<s[ansp])||
(l[i]==l[ansp]&&s[i]==s[ansp]&&l[i]+l0[i]<l[ansp]+l0[ansp]))
ansp = i;
for(i=ansp;i!=n-;i=fr0[i]) fr[fr0[i]] = i, s[fr0[i]] = ;
bool flag = ;
for(i=n-;i;i=fr[i])
{
if(flag||s[i]) putchar('0'+s[i]), flag = ;
ans[++j] = i;
}
if(!flag) putchar('0');
printf("\n%d\n",l[ansp]+l0[ansp]+); ans[++j] = ;
for(i=j;i>;i--) printf("%d ",ans[i]);
printf("%d\n",ans[]);
return ;
}

Bubble Cup 8 finals G. Run for beer (575G)的更多相关文章

  1. Bubble Cup 11 - Finals [Online Mirror, Div. 1]题解 【待补】

    Bubble Cup 11 - Finals [Online Mirror, Div. 1] 一场很好玩的题啊! I. Palindrome Pairs 枚举哪种字符出现奇数次. G. AI robo ...

  2. Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1

    Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1 C. Jumping Transformers 我会状压 DP! 用 \(dp[x][y][ ...

  3. Codeforces Bubble Cup 8 - Finals [Online Mirror] B. Bribes lca

    题目链接: http://codeforces.com/contest/575/problem/B 题解: 把链u,v拆成u,lca(u,v)和v,lca(u,v)(v,lca(u,v)是倒过来的). ...

  4. Bubble Cup X - Finals [Online Mirror]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 组了个菜鸡队打cf上的ACM比赛 比较快做完了8题但是菜的抠脚罚时巨多,所以最后被顶到了19名(居然没出首页) 自己的号自从上次疯狂掉分就没动 ...

  5. Bubble Cup X - Finals [Online Mirror] B. Neural Network country 矩阵快速幂加速转移

    B. Neural Network country time limit per test 2 seconds memory limit per test 256 megabytes Due to t ...

  6. codeforce1046 Bubble Cup 11 - Finals 题解

    比赛的时候开G开了3h结果rose说一句那唯一一个AC的是羊的心态就崩了.. 这套题感觉质量挺好然后就back了下 A: AI robots 有三个限制条件:相互能够看见和智商的差.使用主席树,可以维 ...

  7. Bubble Cup 8 finals I. Robots protection (575I)

    题意: 有一个正方形区域, 要求支持两个操作: 1.放置三角形,给定放置方向(有4个方向,直角边与坐标轴平行),直角顶点坐标,边长 2.查询一个点被覆盖了多少次 1<=正方形区域边长n<= ...

  8. Bubble Cup 8 finals H. Bots (575H)

    题意: 简单来说就是生成一棵树,要求根到每个叶子节点上的路径颜色排列不同, 且每条根到叶子的路径恰有n条蓝边和n条红边. 求生成的树的节点个数. 1<=n<=10^6 题解: 简单计数. ...

  9. Bubble Cup 8 finals F. Bulbo (575F)

    题意: 给定初始位置,查询n次区间,每次查询前可以花费移动距离的代价来移动, 查询时需要花费当前位置到区间内最近的点的距离,求最小代价. 1<=n<=5000,1<=所有位置< ...

随机推荐

  1. ORACLE 博客文章目录(2015-05-27更新)

    从接触ORACLE到深入学习,已有好几年了,虽然写的博客不多,质量也参差不齐,但是,它却是成长的历程的点点滴滴的一个见证,见证了我在这条路上的寻寻觅觅,朝圣的心路历程,现在将ORACLE方面的博客整理 ...

  2. (八)map,filter,flatMap算子-Java&Python版Spark

    map,filter,flatMap算子 视频教程: 1.优酷 2.YouTube 1.map map是将源JavaRDD的一个一个元素的传入call方法,并经过算法后一个一个的返回从而生成一个新的J ...

  3. 安装.NET Framework进度条卡住不动的解决方案

    VS在安装之前需要安装.NET Framework,我安装的是4.0版本.但是安装进度条到一半左右时就卡住不动了.前前后后重试多次,还有几次重新开机,但都没用. 开始还以为是安装的系统有问题.后来在网 ...

  4. Linux系统用户和用户组介绍

    1.请问如下登录环境故障的原理及解决办法? [root@server test]# useradd rr ##创建用户rr [root@server test]# id rr uid=510(rr) ...

  5. mysql初级命令

    修改本地mysql root密码 #mysqladmin -uroot -p原密码 password  现密码 #mysqladmin -uroot -p passwd  password nowwd ...

  6. 树莓派3B初始化后一些必须的设置

    接上一篇,SSH已经登录成功(http://www.cnblogs.com/crosys/p/6220108.html) 1.树莓派系统的设置 1.1扩展系统空间 因为内存卡还有很多空间没有分配,第一 ...

  7. k近邻算法(knn)的c语言实现

    最近在看knn算法,顺便敲敲代码. knn属于数据挖掘的分类算法.基本思想是在距离空间里,如果一个样本的最接近的k个邻居里,绝大多数属于某个类别,则该样本也属于这个类别.俗话叫,"随大流&q ...

  8. java 后台开发关键词解释

    bean类:是一些实体类,包括viewbean,databean等等.action类:可作为接收显示层的数据,连接显示层和业务逻辑实现层的控制层.model类:MVC中model层就是到层.在java ...

  9. .NET和JAVA中BYTE的区别以及JAVA中“DES/CBC/PKCS5PADDING” 加密解密在.NET中的实现

    场景:java 作为客户端调用已有的一个.net写的server的webservice,输入string,返回字节数组. 问题:返回的值不是自己想要的,跟.net客户端直接调用总是有差距 分析:平台不 ...

  10. HDOJ 2393. Higher Math

    Higher Math Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...