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 ...
随机推荐
- React 编码
https://github.com/Minwe/style-guide/blob/master/React.js.md https://github.com/planningcenter/react ...
- Hihocoder 之 #1097 : 最小生成树一·Prim算法 (用vector二维 模拟邻接表,进行prim()生成树算法, *【模板】)
#1097 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可 ...
- springboot在eclipse实现热部署
eclipse使用spring-tool-suite插件创建springboot项目,项目创建完成后. 选中项目,右键 Spring Tools --> Add Boot Devtools 点 ...
- Linux 下WAS的java版本查看
1.查找linux的详细版本号: A.cat /proc/version B.lsb_release -a(可以查出是否为redhat开发的) C.uname -a 2.Linux的java版本 A. ...
- [Selenium] Grid 介绍
Selenium Grid 支持分布式测试,使测试人员可在分布式环境中进行测试 一般而言,在面临以下情况时可考虑使用Selenium Grid : 1.测试多个浏览器或单个浏览器多个版本,或测试不同操 ...
- 理解Objective-C Runtime(三)消息转发机制
消息转发机制概述 上一篇博客消息传递机制中讲解了Objective-C中对象的「消息传递机制」.本文需要讲解另外一个重要问题:当对象受到无法处理的消息之后会发生什么情况? 显然,若想令类能理解某条消息 ...
- [Codeforces 914D] Bash and a Tough Math Puzzle
[题目链接] https://codeforces.com/contest/914/problem/D [算法] 显然 , 当一个区间[l , r]中为d倍数的数的个数 <= 1 , 答案为Ye ...
- ES6之拷贝对象
function copyObject(orig) { var copy = Object.create(Object.getPrototypeOf(orig)); //创建一个新的原型对象 copy ...
- HBase源码分析:HTable put过程
HBase版本:0.94.15-cdh4.7.0 在 HBase中,大部分的操作都是在RegionServer完成的,Client端想要插入.删除.查询数据都需要先找到相应的 RegionServer ...
- Two
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission( ...