spfa它死了

——by 大佬

但是本蒟蒻还是一如既往的使用spfa...

因为太弱了,其他什么都不会。于是就疯狂开O2跪倒在spfa上。

例题——汽车加油行驶问题

loj跳转链接

luogu跳转链接

题目描述

给定一个 N×N 的方形网格,设其左上角为起点◎,坐标为 (1,1)(1,1) ,X 轴向右为正, Y 轴向下为正,每个方格边长为 1 ,如图所示。

一辆汽车从起点◎出发驶向右下角终点▲,其坐标为 (N,N) 。

在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油。汽车在行驶过程中应遵守如下规则:

  • 汽车只能沿网格边行驶,装满油后能行驶 K 条网格边。出发时汽车已装满油,在起 点与终点处不设油库。
  • 汽车经过一条网格边时,若其 X 坐标或 Y 坐标减小,则应付费用 \text{B}B ,否则免付费用。
  • 汽车在行驶过程中遇油库则应加满油并付加油费用 A。
  • 在需要时可在网格点处增设油库,并付增设油库费用 C (不含加油费用 \text{A}A )。
  • N , K , A , B , C 均为正整数, 且满足约束: 102≤N≤100,2≤K≤10。

设计一个算法,求出汽车从起点出发到达终点的一条所付费用最少的行驶路线。

输入格式

文件的第一行是 N,K,A,B,C 的值。

第二行起是一个 N∗N 的 0-1 方阵,每行 N 个值,至 N+1 行结束。

方阵的第 i 行第 j 列处的值为 1 表示在网格交叉点 (i,j) 处设置了一个油库,为 0 时表示未设油库。各行相邻两个数以空格分隔。

输出格式

程序运行结束时,输出最小费用。

样例输入

9 3 2 3 6
0 0 0 0 1 0 0 0 0
0 0 0 1 0 1 1 0 0
1 0 1 0 0 0 0 1 0
0 0 0 0 0 1 0 0 1
1 0 0 1 0 0 1 0 0
0 1 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 1
1 0 0 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0

样例输出

12

思路

当然食用spfa啦。

但本蒟蒻不会分层。所以就二维spfa啦。

基本思路就是:一开始先把(1,1)点的状态扔进队列。

然后分类讨论

没了。。

丑陋无比的代码:

#include<algorithm>
#include<bitset>
#include<complex>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<iterator>
#include<limits>
#include<list>
#include<locale>
#include<map>
#include<memory>
#include<new>
#include<numeric>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<typeinfo>
#include<utility>
#include<valarray>
#include<vector>
#include<cctype>
#include<cerrno>
#include<cfloat>
#include<ciso646>
#include<climits>
#include<clocale>
#include<cmath>
#include<csetjmp>
#include<csignal>
#include<cstdarg>
#include<cstddef>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#define ll long long
#define mod 100003
#define E 1000010
using namespace std;//丑陋的头文件终于结束
inline ll read(){
ll res=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar();
return res*f;
}//丑陋的读优
inline void write(ll x){
if(x<0) putchar('-'),x=-x;
if(x<10) putchar(x+'0');
else{
write(x/10);
putchar(x%10+'0');
}
}//丑陋的输优
//queue<ll> q;
//set<ll> s;
//priority_queue<ll> q1;
//priority_queue<ll,vector<ll>,greater<ll> > q2;
//list<ll> l;
//stack<ll> s;
int n,k,a,b,c;
int has[110][110];//有木有油箱
int dis[110][110][15];//当前状态的最小花费
struct node{
int x,y,z;//状态记录,分别为x坐标、y坐标、还有多少油
};
struct queue{
node val[10000000];int s,t;
void clean(){
memset(val,0,sizeof(val));
s=0;t=0;//清空(貌似没有用到过)
}
void push(node tmp){
++t;
t%=10000000;
val[t]=tmp;//加入队尾
}
inline node front(){
return val[(s+1)%10000000];//循环队列,get队首
}
void pop(){
s++;//弹出
s%=10000000;//循环队列
}
bool empty(){//判断是否为空
if(s>=t) return 1;
else return 0;
}
}q;//队列
node make(int x,int y,int z){
node pp;pp.x=x;pp.y=y;pp.z=z;
return pp;
}//方便快捷一些
const int dx[]={0,0,1,-1},
dy[]={1,-1,0,0};//四个方向
void print(){
system("cls");
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int ss=2e9;
for(int l=0;l<=k;l++) ss=min(ss,dis[i][j][l]);
cout<<ss<<" ";
}
cout<<endl;
}
}//调试输出函数
void spfa(){//spfa开始
while(!q.empty()){
node u=q.front();q.pop();
int x=u.x,y=u.y,K=u.z;//取出队首元素
if(K==0){//没油了
if(has[x][y]==1){//真棒!这里就有油箱
if(dis[x][y][K]+a<dis[x][y][k]){
dis[x][y][k]=min(dis[x][y][k],dis[x][y][K]+a);//加油花费a
q.push(make(x,y,k));
}
}else{//这里没有油箱
if(dis[x][y][k]>dis[x][y][K]+c+a){
dis[x][y][k]=min(dis[x][y][k],dis[x][y][K]+c+a);//新建油箱花费c,加油花费a
q.push(make(x,y,k));
}
}
}else{
if(has[x][y]==1){//坑,如果经过油箱必须加油
if(dis[x][y][K]+a<dis[x][y][k]){
dis[x][y][k]=dis[x][y][K]+a;//愉快的花费a
q.push(make(x,y,k));continue ;//因为加油,本次状态取消,直接退出
}
}
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];//四个方向
if(xx>=1&&xx<=n&&yy>=1&&yy<=n){//判断是否越界
if(dis[xx][yy][K-1]>dis[x][y][K]+((i==1||i==3)?b:0)){//如果往负方向花费b
dis[xx][yy][K-1]=dis[x][y][K]+((i==1||i==3)?b:0);//更新
q.push(make(xx,yy,K-1));//保存状态
}
}
} }
// print();
}
}
int main(){
n=read();k=read();a=read();b=read();c=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
has[i][j]=read();
}
}//丑陋无比的读入
memset(dis,63,sizeof(dis));//初始化
dis[1][1][k]=0;//初始化
q.push(make(1,1,k));//塞入队列
spfa();//spfa
int ans=2e9;//取最小值前设定最大
for(int i=0;i<=k;i++) ans=min(ans,dis[n][n][i]);//更新,因为终点有很多状态,取最小值
cout<<ans<<endl;//输出
return 0;
}

spfa学习笔记的更多相关文章

  1. Day 4 学习笔记 各种图论

    Day 4 学习笔记 各种图论 图是什么???? 不是我上传的图床上的那些垃圾解释... 一.图: 1.定义 由顶点和边组成的集合叫做图. 2.分类: 边如果是有向边,就是有向图:否则,就是无向图. ...

  2. Johnson算法学习笔记

    \(Johnson\)算法学习笔记. 在最短路的学习中,我们曾学习了三种最短路的算法,\(Bellman-Ford\)算法及其队列优化\(SPFA\)算法,\(Dijkstra\)算法.这些算法可以快 ...

  3. Johnson 全源最短路径算法学习笔记

    Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...

  4. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  5. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  6. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  7. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  8. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  9. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

随机推荐

  1. js数组去重五种方法

    今天来聊一聊JS数组去重的一些方法,包括一些网上看到的和自己总结的,总共5种方法(ES5). 第一种:遍历数组法 这种方法最简单最直观,也最容易理解,代码如下: var arr = [2, 8, 5, ...

  2. 【设计模式】—— 访问者模式Visitor

    前言:[模式总览]——————————by xingoo 模式意图 对于某个对象或者一组对象,不同的访问者,产生的结果不同,执行操作也不同.此时,就是访问者模式的典型应用了. 应用场景 1 不同的子类 ...

  3. [代码]--WinForm 窗体之间相互嵌套

    public FrmScan() { InitializeComponent(); Form1 frm = new Form1(); frm.Dock = DockStyle.Fill; frm.Fo ...

  4. 【刷题】BZOJ 4391 [Usaco2015 dec]High Card Low Card

    Description Bessie the cow is a huge fan of card games, which is quite surprising, given her lack of ...

  5. HGOI20180813 (NOIP2018 提高组 Day2 模拟试题)

    省常中省选提高Day2 继续 第一题就考了贪心,正解95pts的贪心策略第一印象是想到的,但是被自己否定掉了qwq,然后打了 不是正解的贪心,样例5没过(可怜)思路如下:先找出每个门对应可以通过的人数 ...

  6. 前端学习 -- Css -- 字体的几个属性学习

    font-style可以用来设置文字的斜体 - 可选值: normal,默认值,文字正常显示 italic 文字会以斜体显示 oblique 文字会以倾斜的效果显示 - 大部分浏览器都不会对倾斜和斜体 ...

  7. 变量&常量

    变量:variables 存储数据,以被后面的程序调用,可以看作是:装信息的容器: 变量的作用:(1)标记数据(2)存储数据 变量定义规范1.声明变量:定义变量   name = "Mr H ...

  8. Python教你找到最心仪的对象

    规则 单身妹妹到了适婚年龄,要选对象.候选男子100名,都是单身妹妹没有见过的.百人以随机顺序,从单身妹妹面前逐一经过.每当一位男子在单身妹妹面前经过时,单身妹妹要么选他为配偶,要么不选.如果选他,其 ...

  9. JVM调优命令-jstat

    JVM Statistics Monitoring Tool,是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载.内存.垃圾收集.JIT编译等运行数据.[性能分析] 命令格式 1 ...

  10. SQL记录-PLSQL变量与常量文字

    PL/SQL变量   变量是只不过是一个给定的存储区域,程序可以操纵的名称.PL/SQL每个变量具有一个特定的数据类型,它决定了大小和变量的存储器的值,可以说存储器和设置操作可以施加到可变内被存储的范 ...