poj1724 ROADS
题意:
N个城市,编号1到N。城市间有R条单向道路。
每条道路连接两个城市,有长度和过路费两个属性。
Bob只有K块钱,他想从城市1走到城市N。问最短共需要走多长的路。如果到不了N,输出-1
2<=N<=100
0<=K<=10000
1<=R<=10000
每条路的长度 L, 1 <= L <= 100
每条路的过路费T , 0 <= T <= 100
思路:
用d[i][j]表示从源点走到城市i并且花费为j的时候经过的最短距离。若在后续的搜索中,再次走到i时,如果总路费恰好为j,且此时的路径长度已经超过 d[i][j],则不必再走下去了。
1.深搜+剪枝
2.spfa+剪枝
实现:
1.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std; const int MAXN = ;
const int MAXK = ;
const int INF = 0x3f3f3f3f; struct node
{
int to, len, toll;
};
vector<node> G[MAXN + ];
int k, n, m, s, t, l, T, minLen = INF; bool vis[MAXN + ];
int d[MAXN + ][MAXK + ]; void dfs(int now, int rem, int len)
{
if (now == n)
{
minLen = min(minLen, len);
return;
}
for (int i = G[now].size() - ; i >= ; i--)
{
if (!vis[G[now][i].to] && rem >= G[now][i].toll)
{
if (d[G[now][i].to][rem - G[now][i].toll] <=
len + G[now][i].len || len + G[now][i].len >= minLen)
continue;
d[G[now][i].to][rem - G[now][i].toll] = len + G[now][i].len;
dfs(G[now][i].to, rem - G[now][i].toll, len + G[now][i].len);
vis[G[now][i].to] = false;
}
}
} int main()
{
cin >> k >> n >> m;
for (int i = ; i < m; i++)
{
cin >> s >> t >> l >> T;
node tmp;
tmp.to = t;
tmp.len = l;
tmp.toll = T;
if (s != t)
G[s].push_back(tmp);
}
memset(d, 0x3f, sizeof(d));
vis[] = true;
dfs(, k, );
if (minLen == INF)
puts("-1");
else
cout << minLen << endl;
return ;
}
2.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <functional>
using namespace std; const int MAXN = ;
const int MAXK = ;
const int INF = 0x3f3f3f3f; struct node
{
int to, len, toll;
};
vector<node> G[MAXN + ];
int k, n, m, s, t, l, T; struct co
{
int now, cost;
}; int d[MAXN + ][MAXK + ];
int in[MAXN + ][MAXK + ]; int spfa()
{
queue<co> q;
co start;
start.now = ;
start.cost = ;
q.push(start);
in[][] = true;
priority_queue<int, vector<int>, greater<int> > pq;
pq.push(INF);
while (!q.empty())
{
co tmp = q.front();
q.pop();
int now = tmp.now;
int cost = tmp.cost;
if (now == n)
{
pq.push(d[n][cost]);
}
in[now][cost] = false;
for (int i = ; i < G[now].size(); i++)
{
if (cost + G[now][i].toll <= k &&
d[now][cost] + G[now][i].len < d[G[now][i].to][cost + G[now][i].toll])
{
d[G[now][i].to][cost + G[now][i].toll] = d[now][cost] + G[now][i].len;
if (d[G[now][i].to][cost + G[now][i].toll] >= pq.top())
continue;
if (!in[G[now][i].to][cost + G[now][i].toll])
{
in[G[now][i].to][cost + G[now][i].toll] = true;
co son;
son.now = G[now][i].to;
son.cost = cost + G[tmp.now][i].toll;
q.push(son);
}
}
}
}
int minL = INF;
for (int i = ; i <= k; i++)
{
minL = min(minL, d[n][i]);
}
return minL;
} int main()
{
cin >> k >> n >> m;
for (int i = ; i < m; i++)
{
cin >> s >> t >> l >> T;
node tmp;
tmp.to = t;
tmp.len = l;
tmp.toll = T;
if (s != t)
G[s].push_back(tmp);
}
memset(d, 0x3f, sizeof(d));
for (int i = ; i <= k; i++)
{
d[][i] = ;
}
int minLen = spfa();
if (minLen >= INF)
puts("-1");
else
cout << minLen << endl;
return ;
}
最优性剪枝总结:
1. 从初始状态到当前状态的代价已经不小于目前找到的最优解,则剪枝。
2. 预测一下从当前状态到解的状态至少要花的代价W,如果W加上到达当前状态时已经花费的代价,必然不小于目前找到的最优解,则剪枝。
3. 如果到达某个状态A时,发现前面曾经也到达过A,且前面那次到达A所花代价更少,则剪枝。这要求记录到目前为止到达状态A时所能取得的最小代价。
poj1724 ROADS的更多相关文章
- 有限制的最短路spfa+优先队列
poj1724 ROADS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10751 Accepted: 3952 De ...
- poj分类解题报告索引
图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Jou ...
- POJ 1724 ROADS(使用邻接表和优先队列的BFS求解最短路问题)
题目链接: https://cn.vjudge.net/problem/POJ-1724 N cities named with numbers 1 ... N are connected with ...
- poj 1251 Jungle Roads (最小生成树)
poj 1251 Jungle Roads (最小生成树) Link: http://poj.org/problem?id=1251 Jungle Roads Time Limit: 1000 ...
- Jungle Roads[HDU1301]
Jungle Roads Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- POJ1947 Rebuilding Roads[树形背包]
Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 11495 Accepted: 5276 ...
- Constructing Roads——F
F. Constructing Roads There are N villages, which are numbered from 1 to N, and you should build som ...
- Constructing Roads In JGShining's Kingdom(HDU1025)(LCS序列的变行)
Constructing Roads In JGShining's Kingdom HDU1025 题目主要理解要用LCS进行求解! 并且一般的求法会超时!!要用二分!!! 最后蛋疼的是输出格式的注 ...
- 【CodeForces 567E】President and Roads(最短路)
Description Berland has n cities, the capital is located in city s, and the historic home town of th ...
随机推荐
- (linux)MMC 卡驱动分析
最近花时间研究了一下 MMC 卡驱动程序,开始在网上找了很多关于 MMC 卡驱动的分析文章,但大都是在描述各个层,这对于初学者来讲帮助并不大,所以我就打算把自己的理解写下来,希望对大家有用.个人觉得理 ...
- linux设备驱动学习笔记(1)
学习了将近半个月的设备驱动程序的编写,也有一些体会,这里写下来也给学习做一个总结,为后面的学习做更好的准备. 首先,个人感觉驱动程序的设计是很有套路的,最基本的要求就是要掌握这些套路.所谓的套路就是一 ...
- CentOS 7.2安装Jenkins自动构建Git项目
1.环境 本文使用VMWare虚拟机进行实验. 最终实现目标,在Jenkins服务器上新建构建任务,从Git服务器上拉取master HEAD(不编译,仅演示),部署到"目标服务器" ...
- bzoj3957: [WF2011]To Add or to Multiply
gay队牛逼! 我们可以强行拆一下柿子,最终得到的值会是m^k*x+m^k*u(k)*a+m^k-1*u(k-1)*a……m^0*u(0)*a 其中u表示后面有i个m的a有多少个 答案就是k+∑u 枚 ...
- 计算机学院大学生程序设计竞赛(2015’12)Study Words
Study Words Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- Spring配置错误 No adapter for IAdvice of type
参考:http://www.2cto.com/kf/201305/211728.html 错误十三 在配置拦截器后,运行的时候报错=> Error creating context 'sprin ...
- bzoj2560串珠子——子集DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2560 转载: 很明显的状压dp 一开始写的dp可能会出现重复统计的情况 而且难以去重 假设 ...
- Code:zabbix 目录
ylbtech-Code:zabbix 目录 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http://y ...
- (二十五)后台开发-分类信息的curd -展示所有实现
案例1-分类信息的curd 步骤分析: 左边的dtree: 1.导入dtree.js 2.导入dtree.css 3.创建一个div 添加样式 class="dtree" 4.在d ...
- Android 实用技巧 --- 命令godir (转载)
转自:http://blog.csdn.net/bigmarco/article/details/6995426 source build/envsetup.sh后可以使用很多android集成的sh ...