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 ...
随机推荐
- YSU小吃街
贪心贪不过,暴力搜就完事了 注意不连通情况 #include<iostream> #include<sstream> #include<cstdio> #inclu ...
- MindSpore:基于本地差分隐私的 Bandit 算法
摘要:本文将先简单介绍Bandit 问题和本地差分隐私的相关背景,然后介绍基于本地差分隐私的 Bandit 算法,最后通过一个简单的电影推荐场景来验证 LDP LinUCB 算法. Bandit问题是 ...
- 爬虫必知必会(7)_scrapy框架高级
一.请求传参 实现深度爬取:爬取多个层级对应的页面数据 使用场景:爬取的数据没有在同一张页面中 在手动请求的时候传递item:yield scrapy.Request(url,callback,met ...
- SpringMVC-06 Ajax
SpringMVC-06 Ajax Ajax 1.简介 AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 是一种在无 ...
- MyBatis的XML配置文件
属性(properties) 通过properties的子元素设置配置项: <properties> <property name="driver" value= ...
- 洛谷P1290欧几里德游戏
题目地址 题目大意: 两个人st和ol博弈 有两个整数n,m 每次轮到一个人时候,需要选择用大的那个数减去小的那个数的倍数(不能减为负数) 最后得到0的为胜利者 思路: (以下讨论均在n<m的条 ...
- redis常用数据类型对应的数据结构
redis的数据类型都是通过多种数据结构来实现,主要是出于时间和空间的考虑,当数据量小的时候通过数组下标访问最快,占用内存最小[压缩列表是数组的变种,允许存储的数据大小不同] 因为数组需要占用连续的内 ...
- 设计原则:开闭原则(OCP)
1.什么是开闭原则 开闭原则的英文是Open Closed Principle,缩写就是OCP.其定义如下: 软件实体(模块.类.方法等)应该"对扩展开放.对修改关闭". 从定义上 ...
- OO_Unit1总结
OO的第一单元作业告一段落,这周是总结而不是码代码,甚至心中有点落空感.OO课给我的一周构建了一个完整的循环,从周二的作业发布到接下来几天的思考和构建程序,再到面向中测进行一部分的bug修复,最后到互 ...
- (五)Struts2处理结果管理
当Action处理完用户请求时,处理结果应该通过视图资源实现,但将哪个视图呈现给浏览者呢.由<result.../>来决定 Action处理完用户请求后,返回一个普通字符串.整个普通字符串 ...