题意:

     给你一个有向图,然后求从起点到终点的最短,但是还有一个限制,就是总花费不能超过k,也就是说每条边上有两个权值,一个是长度,一个是花费,求满足花费的最短长度。

思路:

      一开始写了一个mark[i][j]第i个点花费j状态的spfa,TLE了,然后又优化了下,就是先反向搜索一遍简单最短路(以花费为权值)然后用这个结果在mark[][]二维的最短路里面剪枝用,结果还是超时了,然后又尝试了下优先队列,结果900+ac险过,我把自己的第一个优化去掉,结果跑了800+,哎!对于在spfa上使用优先队列,这个我感觉还是不是很靠谱啊,如果不考虑优先队列的时间复杂度跑spfa确实是个优化,因为毕竟有点贪心的意思(具体能优化多少,要看数据,总之不会像记忆化搜索那样级别的优化就是了),可是优先队列的操作时间是log级别的,在他们两个之间去衡量,还是要看具体数据啊。

这是个有反向搜索预处理优化的ac代码,把反向预处理去掉之后会更快一点(哎!)

#include<queue>

#include<stdio.h>

#include<string.h>

#define N_node 100 + 5

#define N_edge 10000 + 10

#define INF 100000000

using namespace std;

typedef struct

{

    int to ,next ,cost ,time;

}STAR;

typedef struct

{

    int to ,next ,cost;

}STAR2;

typedef struct NODE

{

    int id ,cost ,time;

    friend bool operator < (NODE a ,NODE b)

    {

        return a.cost > b.cost || a.cost == b.cost && a.time > b.time;

    }

}NODE;

int list[N_node] ,tot;

int list2[N_node] ,tot2;

int mark[N_node][10000+5];

int  s_x[N_node][10000+5];

int s_x2[N_node];

STAR E[N_edge];

STAR2 E2[N_edge];

NODE xin ,tou;

void add(int a ,int b ,int c ,int d)

{

    E[++tot].to = b;

    E[tot].cost = c;

    E[tot].time = d;

    E[tot].next = list[a];

    list[a] = tot;

}

void add2(int a ,int b ,int c)

{

    E2[++tot2].to = b;

    E2[tot2].cost = c;

    E2[tot2].next = list2[a];

    list2[a] = tot2;

}

void Spfa(int s ,int n ,int maxtime)

{

    for(int i = 0 ;i <= n ;i ++)

    for(int j = 0 ;j <= maxtime ;j ++)

    s_x[i][j] = INF ,mark[i][j] = 0;

    priority_queue<NODE>q;

    xin.id = 1 ,xin.cost = xin.time = 0;

    q.push(xin);

    s_x[xin.id][xin.time] = 0;

    mark[xin.id][xin.time] = 1;

    while(!q.empty())

    {

        tou = q.top();

        q.pop();

        mark[tou.id][tou.time] = 0;

        for(int k = list[tou.id] ;k ;k = E[k].next)

        {

            xin.id = E[k].to;

            xin.cost = tou.cost + E[k].cost;

            xin.time = tou.time + E[k].time;

            if(xin.time + s_x2[xin.id]> maxtime) continue;

            if(s_x[xin.id][xin.time] > s_x[tou.id][tou.time] + E[k].cost)

            {

                s_x[xin.id][xin.time] = s_x[tou.id][tou.time] + E[k].cost;

                if(!mark[xin.id][xin.time])

                {

                    mark[xin.id][xin.time] = 1;

                    q.push(xin);

                }

            }

        }

    }

}

void Spfa2(int s ,int n)

{

    int mk[N_node] = {0};

    for(int i = 0 ;i <= n ;i ++)

    s_x2[i] = INF;

    queue<int>q;

    q.push(s);

    mk[s] = 1;

    s_x2[s] = 0;

    while(!q.empty())

    {

        int xin ,tou;

        tou = q.front();

        q.pop();

        mk[tou] = 0;

        for(int k = list2[tou] ;k ;k = E2[k].next)

        {

            xin = E2[k].to;

            if(s_x2[xin] > s_x2[tou] + E2[k].cost)

            {

                s_x2[xin] = s_x2[tou] + E2[k].cost;

                if(!mk[xin])

                {

                    mk[xin] = 1;

                    q.push(xin);

                }

            }

        }

    }

}

int main ()

{

    int n ,m ,maxtime ,i;

    int a ,b ,c ,d;

    while(~scanf("%d" ,&maxtime))

    {

        scanf("%d %d" ,&n ,&m);

        memset(list ,0 ,sizeof(list));

        memset(list2 ,0 ,sizeof(list2));

        tot = 1 ,tot2 = 1;

        for(i = 1 ;i <= m ;i ++)

        {

            scanf("%d %d %d %d" ,&a ,&b ,&c ,&d);

            add(a ,b ,c ,d);

            add2(b ,a ,d);

        }

        Spfa2(n ,n);

        Spfa(1 ,n ,maxtime);

        int ans = INF;

        for(i = 1 ;i <= maxtime ;i ++)

        if(ans > s_x[n][i]) ans = s_x[n][i];

        if(ans == INF) ans = -1;

        printf("%d\n" ,ans);

    }

    return 0;

}

POJ1722二维spfa+优先队列优化的更多相关文章

  1. Firemonkey 原生二维码扫描优化

    之前用了ZXing的Delphi版本,运行自带的例子,速度非常慢,与安卓版本的相比查了很多,因此打算使用集成jar的方法,但是总觉得美中不足. 经过一番研究,基本上解决了问题. 主要有两方面的优化: ...

  2. (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例

    Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21我要评论 这篇文章主要介绍了Android项目 ...

  3. 01二维背包+bitset优化——hdu5890

    口胡一种别的解法: 三重退背包,g1[j]k]表示不选x的选了j件物品,体积为k的方案数,g[0][0] = 1 , g1[j][k]=dp[j][k]-g1[j-1][k-a[x]] 然后按这样再退 ...

  4. 洛谷 P5471 - [NOI2019] 弹跳(二维线段树优化建图+堆优化存边)

    题面传送门 一道非常有意思的题(大概可以这么形容?) 首先看到这类一个点想一个区域内连边的题目可以很自然地想到线段树优化建图,只不过这道题是二维的,因此需要使用二维线段树优化建图,具体来说,我们外层开 ...

  5. POJ 1724 ROADS(二维SPFA)

    题目链接 用STL实现超时了,用普通队列500+,看到spfa,反应太迟钝了. #include <cstring> #include <cstdio> #include &l ...

  6. SDUT 最短路径(二维SPFA)

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2622 #include<stdio.h& ...

  7. POJ 2686 Traveling by Stagecoach(状压二维SPFA)

    Traveling by Stagecoach Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3407   Accepted ...

  8. BZOJ3577:玩手机(最大流,二维ST表)

    Description 现在有一堆手机放在坐标网格里面(坐标从1开始),坐标(i,j)的格子有s_(i,j)个手机. 玩手机当然需要有信号,不过这里的手机与基站与我们不太一样.基站分为两种:发送站和接 ...

  9. Android利用zxing生成二维码

    感谢大佬:https://blog.csdn.net/mountain_hua/article/details/80646089 **gayhub上的zxing可用于生成二维码,识别二维码 gayhu ...

随机推荐

  1. OSI协议简述版

    OSI简介 OSI只是计算机网络中的一种协议名称缩写,它只是电脑间传输数据的协议,并不代表具体的物理设备,并且这种协议,只是被人为的划分为五层:物理层.数据链路层.网络层.传输层.应用层.记住,它只是 ...

  2. java将一个list转换成一个String,中间用分隔符隔开

    List sn=[123,1231,1231,231] sn.toString();//[123,1231,1231,231] sn.join(',').toString();//123,1231,1 ...

  3. golang——net/rpc包学习

    1.rpc包 rpc包提供了通过网络或其他I/O连接对一个对象的导出方法的访问. 只有满足如下标准的方法才能用于远程访问,其余方法会被忽略: (1)方法是导出的(2)方法有两个参数,都是导出类型或内建 ...

  4. FreeBSD 中文TTY控制台

    freebsd新型终端VT,支持cjk,所以丢个字体进去,就能显示中文了1,首先你没有改过控制台程序,使用的是默认的,,2,最新版本,本说明是以freebsd12.1release字体格式为.fnt命 ...

  5. FreeBSD 虚拟网卡 网桥 路由 映射

    网关与路由 netstat -r Routing tables #路由表 Destination Gateway Flags Refs Use Netif Expire 目的地 网关 状态 接口 超时 ...

  6. 翻译:《实用的Python编程》04_04_Defining_exceptions

    目录 | 上一节 (4.3 特殊方法) | 下一节 (5 对象模型) 4.4 定义异常 用户可以通过类实现自定义异常: class NetworkError(Exception): pass **异常 ...

  7. CSS篇-样式表、选择器、权重、伪类

    CSS定义 CSS:Cascading Style Sheet(层叠样式表) // 写法 选择器 { 属性名: 属性值; } CSS样式表 (1)三种样式表使用 // 内联样式 <div sty ...

  8. 手把手教你docker安装宝塔面板

    手把手教你docker安装宝塔面板(针对小白提一下:需要先安装docker,安装docker的教程请自行百度,非常简单的),docker安装宝塔面板教程如下: 一.拉取centos镜像(当然这里拉取别 ...

  9. 【秒懂音视频开发】12_播放WAV

    对于WAV文件来说,可以直接使用ffplay命令播放,而且不用像PCM那样增加额外的参数.因为WAV的文件头中已经包含了相关的音频参数信息. ffplay in.wav 接下来演示一下如何使用SDL播 ...

  10. 有了CMDB,为什么还需要应用配置管理?

    有了CMDB,为什么还需要应用配置管理? 你不妨先停下来,思考一下这个问题. 我抛出的观点是: CMDB是面向资源的管理,应用配置是面向应用的管理. 请注意,这里是面向"资源",不 ...