POJ1722二维spfa+优先队列优化
题意:
给你一个有向图,然后求从起点到终点的最短,但是还有一个限制,就是总花费不能超过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+优先队列优化的更多相关文章
- Firemonkey 原生二维码扫描优化
之前用了ZXing的Delphi版本,运行自带的例子,速度非常慢,与安卓版本的相比查了很多,因此打算使用集成jar的方法,但是总觉得美中不足. 经过一番研究,基本上解决了问题. 主要有两方面的优化: ...
- (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例
Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21我要评论 这篇文章主要介绍了Android项目 ...
- 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]] 然后按这样再退 ...
- 洛谷 P5471 - [NOI2019] 弹跳(二维线段树优化建图+堆优化存边)
题面传送门 一道非常有意思的题(大概可以这么形容?) 首先看到这类一个点想一个区域内连边的题目可以很自然地想到线段树优化建图,只不过这道题是二维的,因此需要使用二维线段树优化建图,具体来说,我们外层开 ...
- POJ 1724 ROADS(二维SPFA)
题目链接 用STL实现超时了,用普通队列500+,看到spfa,反应太迟钝了. #include <cstring> #include <cstdio> #include &l ...
- SDUT 最短路径(二维SPFA)
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2622 #include<stdio.h& ...
- POJ 2686 Traveling by Stagecoach(状压二维SPFA)
Traveling by Stagecoach Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 3407 Accepted ...
- BZOJ3577:玩手机(最大流,二维ST表)
Description 现在有一堆手机放在坐标网格里面(坐标从1开始),坐标(i,j)的格子有s_(i,j)个手机. 玩手机当然需要有信号,不过这里的手机与基站与我们不太一样.基站分为两种:发送站和接 ...
- Android利用zxing生成二维码
感谢大佬:https://blog.csdn.net/mountain_hua/article/details/80646089 **gayhub上的zxing可用于生成二维码,识别二维码 gayhu ...
随机推荐
- [个人总结]pytorch中用checkpoint设置恢复,在恢复后的acc上升
原因是因为checkpoint设置好的确是保存了相关字段.但是其中设置的train_dataset却已经走过了epoch轮,当你再继续训练时候,train_dataset是从第一个load_data开 ...
- Java数据持久层
一.前言 1.持久层 Java数据持久层,其本身是为了实现与数据源进行数据交互的存在,其目的是通过分层架构风格,进行应用&数据的解耦. 我从整体角度,依次阐述JDBC.Mybatis.Myba ...
- SVN同步方式举例 FreeBSD
FreeBSD base 默认安装了svnlite 不需要单独安装SVN 软件 svnlite co svn.freebsd.org/ports/head/ /usr/local/ports -r5 ...
- 主成分分析 | Principal Components Analysis | PCA
理论 仅仅使用基本的线性代数知识,就可以推导出一种简单的机器学习算法,主成分分析(Principal Components Analysis, PCA). 假设有 $m$ 个点的集合:$\left\{ ...
- 【LeetCode】10.Regular Expression Matching(dp)
[题意] 给两个字符串s和p,判断s是否能用p进行匹配. [题解] dp[i][j]表示s的前i个是否能被p的前j个匹配. 首先可以分成3大类情况,我们先从简单的看起: (1)s[i - 1] = p ...
- 通过《第一行代码》学习 Android 开发
第一行代码 Android --第 2 版-- 郭霖 著 第 1 章:开始启程--你的第一行 Android 代码 •1.2 手把手带你搭建开发环境 Android Studio 的安装及配置 A ...
- macbook/macOS下打开多个相同应用(应用多开)
1.部分应用可使用common+n快捷键.如qq:打开qq主界面后使用common+n即可新起一个qq程序. 2.在终端使用命令 open -n +程序路径.如启动多个qq : open -n /A ...
- 【软件推荐】使用Cmder替换Windows自带的控制台
安装地址 进入cmder官网,下载相应版本. 如果本地已经安装了git,可以选择mini版本. 将 λ 替换为 $ 当前cmder默认的提示符是λ,看上去总是有点不习惯. 打开cmder目录下的ven ...
- BUAA防脱发第一抗连——团队介绍
项目 内容 这个作业属于哪个课程 2021学年春季软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-团队介绍 我在这个课程的目标是 锻炼在大规模开发中的团队协作能力 这个作业在哪个具体方面帮助我 ...
- 结对编程_stage2
项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 结对项目-第二阶段 我在这个课程的目标是 从实践中学习软件工程相关知识(结构化分析和设计方法.敏捷开发方法. ...