dis

[luogu]P1016 旅行家的预算[贪心]

耗尽温柔 提交于 2019-12-26 05:36:35
[luogu]P1016 旅行家的预算 题目描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,…,N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。 输入输出格式 输入格式: 第一行,D1,C,D2,P,N。 接下来有N行。 第i+1行,两个数字,油站i离出发点的距离Di和每升汽油价格Pi。 输出格式: 所需最小费用,计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。 输入输出样例 输入样例1#: 275.6 11.9 27.4 2.8 2 102.0 2.9 220.0 2.2 输出样例1#: 26.95 【数据范围】 N<=6 贪心,每次找最近的比当前价格便宜的加油站,刚好开到那,如果没有,就把油加满,开往下一个目的地。 代码: 1 //2017.10.31 2 //greedy 3 #include<iostream> 4 #include<cstdio> 5 #include<cstring> 6 #include<algorithm> 7 using namespace

数据结构与算法题目集 7-9 旅游规划

五迷三道 提交于 2019-12-16 00:01:52
7-9 旅游规划 (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。 输入格式: 输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。 输出格式: 在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。 输入样例: 4 5 0 3 0 1 1 20 1 3 2 30 0 3 4 10 0 2 2 20 2 3 1 20 输出样例: 3 40 题解: #include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int maxn = 510; bool vis[maxn]; int n, m, s, t, g[maxn][maxn], p[maxn][maxn];

摘抄 python dict() 比 {} 慢6倍左右

你说的曾经没有我的故事 提交于 2019-12-12 22:16:08
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 看了一个叫 doug hellmann 的哥们儿写的博文 在python2.7中 dict() 函数方式生成字典比直接{}要慢6倍。 实验代码 $ python2.7 -m timeit -n 1000000 -r 5 -v 'dict()' raw times: 0.24 0.24 0.24 0.239 0.24 1000000 loops, best of 5: 0.239 usec per loop $ python2.7 -m timeit -n 1000000 -r 5 -v '{}' raw times: 0.0417 0.0413 0.0407 0.0411 0.042 1000000 loops, best of 5: 0.0407 usec per loop 我在自己机器上试了下,由于是windows 要把单引号换成双引号 ,结果一样。 C:\Users\xxxx>python -m timeit -n 1000000 -r 5 -v "dict()" raw times: 0.195 0.194 0.193 0.191 0.191 1000000 loops, best of 5: 0.191 usec per loop C:\Users\xxxx>python -m timeit -n

题解 [51nod1340]地铁环线

☆樱花仙子☆ 提交于 2019-12-07 22:37:39
题解 [51nod1340]地铁环线 题面 解析 本文参考这篇博客 一开始看到只有120行就打算写一写, 结果一刚就是三个星期 摆摆摆 本来是当查分约束入门学的. step 1 首先来考虑下如果已知总长度 \(s\) 如何判断是否合法. 显然差分约束 对于 \(dis(x,y)>=w\) 这个式子等价于 \(dis[x]+w<=dis[y]\) , 即 \(dis[y]+(-w)>=dis[x]\) . 因此, 若 \(x<y\) ,则 \(y\) 向 \(x\) 连一条边权为 \(-w\) 的边. 若 \(x>y\) ,则 \(y\) 向 \(x\) 连一条边权为 \(s-w\) 的边(要绕一圈,yy一下就知道了). 对于 \(dis(x,y)<=w\) 这个式子就是 \(dis[x]+w>=dis[y]\) . 若 \(x<y\) ,则 \(x\) 向 \(y\) 连一条边权为 \(w\) 的边. 若 \(x>y\) ,则 \(x\) 向 \(y\) 连一条边权为 \(s+w\) 的边. 又因为边权至少为 \(1\) ,即 \(dis[x]+1<=dis[y]\) . \(dis[y]+(-1)>=dis[x]\) . 因此 \(i+1\) 要向 \(i\) 连一条边权为 \(-1\) 的边(n-1要特判) 最后,跑n-1边Bellman_Ford, 若还能进行松弛操作

差分约束

不打扰是莪最后的温柔 提交于 2019-12-06 08:45:11
差分约束通常用来求不等式组的可行解。 差分约束的步骤: 1.先将每个不等式xi <= xj + w,转化成一条从xj走到xi的长度为w的一条边。 2.找一个超级源点,使得从该源点开始可以遍历所有边。 3.从源点开始求一遍单源最短路,如果存在负环,则原不等式无解,如果没有负环,则dis[i]就是原不等式的一个可行解。 差分约束求不等式组最大值最小值: 如果求最小值,则应该求最长路,求最大值,应该求最短路。 如果没有一个超级源点可以遍历所有边,就自己设置一个超级源点。 求xi的最大值:求所有从xi出发,形成不等式xi <= xj + w1 <= xk + w1 ...<= w1 + w2 + w3 ...+ w所计算出的上界,xi的最大值等于所有上界的最小值。 银河 由题求得是最小值。所以用最长路。 根据题意: 1.当T = 1,A >= B, B >= A。 2.当T = 2, B >= A + 1。 3.当T = 3,A >= B。 4.当T = 4, A >= B + 1。 5.当T = 5,B >= A。 从0向所有的点连一条长度为1的 边,即Xi >= 0 + 1。 代码: 1 #include <algorithm> 2 #include <cstring> 3 #include <stack> 4 5 using namespace std; 6 7 typedef

[牛客]十二桥问题 解题报告

独自空忆成欢 提交于 2019-12-04 06:27:10
[牛客]十二桥问题 题意 有一张 \(n\) 个点 \(m\) 条边的带权有向图 \((n \le 50000,\ m \le 200000)\) , 其中有 \(k\) 条边是一定要经过的 \((k \le 12)\) , 从节点 \(1\) 出发, 求 : 经过了所有必须经过的边之后,又回到节点 \(1\) 的最短路径. 思路 首先, 虽然点的数量比较大, 但是大部分是没用的, 我们只需要关注必须经过的那几条边 (称为桥) 的端点. 所以, 一开始先分别以 \(1\) 节点和所有桥的端点作为起点, 跑若干遍 \(dijkstra\) , 并用这若干个点之间的最短距离建一张新图. 然后, 考虑状压dp, 设 \(f[u][i]\) 为到了当前点为 \(u\) , 经过的边集(桥集)为 \(i\) 时的最短路径. 但由于这是一张无向图, 没有拓扑序, 无法直接dp, 所以, 我们每次枚举到一个边集时, 先更新所有选到的桥的端点的 \(f\) 值, 并把这些点加入优先队列里, 然后跑一边 dijkstra, 把剩下的所有点都更新. 代码 #include<bits/stdc++.h> #define ll long long #define mkp make_pair using namespace std; const int N=5e4+7; const int M=2e5+7;

bzoj2007/luoguP2046 海拔(平面图最小割转对偶图最短路)

别说谁变了你拦得住时间么 提交于 2019-12-04 04:17:04
题目描述: bzoj luogu 题解时间: 首先考虑海拔待定点的$h$都应该是多少 很明显它们都是$0$或$1$,并且所有$0$连成一块,所有$1$连成一块 只有海拔交界线对答案有贡献,变成了最小割 但是数据范围很明显不能直接跑网络流 由于这是一个平面图,所以根据套路想到: 平面图最小割=对偶图最小环=最外一块面积分成$S$和$T$跑最短路 从左上角往右下角画一条线把外面一块分成$S$和$T$之后建图。 但是要注意这张图上同一条边两个方向权值不同。 那么建边也按照相同方向,即对应向右下方向的边的新建边为$S$->$T$方向,向左上的反之。 然后就可以跑最短路了。 #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; typedef long long lint; namespace LarjaIX { const int N=511; int n,id[N][N]; struct sumireko{int to,ne,w;}e[N*N*8]; int he[N*N*2],ecnt; void addline(int f,int t,int w) { e[++ecnt].to=t,e[ecnt].w=w; e[ecnt].ne=he[f],he[f]

USACO4.1 Fence Loops【最小环·边->点转化】

做~自己de王妃 提交于 2019-12-03 11:38:19
数据不是很大,如果要转换为正常的那种建图方式的话,可以给点进行标号,用一个二维数组存这两条边相交的那个点的标号,方便处理。一定要注意不要同一个点使用不同的编号也不要不同的点使用同一个编号 (这不是废话嘛) 不展开。 想多说一下一种比较有意思的做法,就是把边看成点,把边权转化为点权。 这样的话,原本的最小环长就变成了一条路径上经过的所有点的点权之和啦。 大概,张这个样子吧: 边是没有权值的,它只表示连通性。 不过由于把边看成了点,所以处理有些特殊: 原本的$dis[i][j]$是指点$i$到点$j$所经过的边权之和的最小值,但边->点之后,就变成了点$i$到点$j$所经过的点权之和的最小值(含点$i$和点$j$),那么在转移的时候,原本的方程式$dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j])$就不能用,因为$dis[i][k]$和$dis[k][j]$都包含了点$k$的点权,所以要减去,应该写成这个样子: $$dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]-pw[k]/*point-weight*/)$$ 然后就用$floyd$求最小环就可以了 ->$break$ $in$ $something$ 简单说一下$floyd$求最小环,感觉就是做一遍$floyd$答案就是$dis[i][i]$。 但是不行啊

分层图最短路讲解+例题洛谷P4568[JLOI2011]飞行路线

淺唱寂寞╮ 提交于 2019-12-03 05:00:08
分层图最短路。。。听起来有点高大上,其实就只是相当于三维的最短路而已,和三维迷宫一样,我们用dis[i][k]表示起点S到第k层i的最短路,其中同层的图如果是无向图,继续保持,然后用一条由该层指向上一层的有向线段并且费用为0,作为该层到上一层的道路,实际上就是这样的: 由该层向上一层改点的相邻点建边,建完之后就可以直接开始跑最短路了,当然,有2种跑法,(一)可以将k层的点全部列出来,也就是总共k*n个点,然后建很多的边,最后跑最短路,结果访答案的时候: for (int i=0; i<=k; i++) ans=min(ans,dis[t+i*n]); (二)普通建边,在跑最短路的队列里面进行操作,这个就比较方便,下面给出代码: void dij(int st,int ed,int k,int n) { priority_queue<node>q; q.push(node{st,0,0}); dis[st][0]=0; while (!q.empty()){ node now=q.top(); q.pop(); int id=now.id%n,fl=now.floor; if (vis[id][fl]) continue; vis[id][fl]=1; for (int i=head[id]; i!=-1; i=eg[i].next){//同层最短路 int v=eg[i].to;

P5590 【赛车游戏】

a 夏天 提交于 2019-12-03 02:47:08
果然我还是太 \(Naive\) 了 首先有一些点/边其实是没有意义的,如果从1出发不能到该点或者从该点不能到n,这个点就可以不用管了。这个过程可以用正反两边 \(dfs/bfs\) 实现 然后删掉那些点之后,新图中如果出现了环,那么显然是无解的 然后现在图就转化成了一张 \(DAG\) 由于 \(1->n\) 的所有路径是定值,那么 \(1->\) 新图中所有点的路径都应该是一个定值(反证一下就知道了) 然后我们发现,对于每一条边 \(u->v\) ,实际上是要满足 \(1≤dis_v - dis_u ≤ 9\) ,不难发现这是一个 差分约束 模型 移一下项,我们有: \(dis_u+1≤dis_v\) , \(dis_v-9≤dis_u\) 于是对于每一条边 \((u, v)\) ,我们连一条 \((u, v, 1)\) 和一条 \((u, v, -9)\) 即可 \(Code:\) 不知道为什么只有30,先咕一会,调出来再放 好了调出来了,不连通的那些边的终点起点忘记输出了 #include<bits/stdc++.h> using namespace std; #define il inline #define re register il int read() { re int x = 0, f = 1; re char c = getchar(); while(c <