题意:

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的更多相关文章

  1. 有限制的最短路spfa+优先队列

    poj1724 ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10751   Accepted: 3952 De ...

  2. poj分类解题报告索引

    图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Jou ...

  3. POJ 1724 ROADS(使用邻接表和优先队列的BFS求解最短路问题)

    题目链接: https://cn.vjudge.net/problem/POJ-1724 N cities named with numbers 1 ... N are connected with ...

  4. poj 1251 Jungle Roads (最小生成树)

    poj   1251  Jungle Roads  (最小生成树) Link: http://poj.org/problem?id=1251 Jungle Roads Time Limit: 1000 ...

  5. Jungle Roads[HDU1301]

    Jungle Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  6. POJ1947 Rebuilding Roads[树形背包]

    Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 11495   Accepted: 5276 ...

  7. Constructing Roads——F

    F. Constructing Roads There are N villages, which are numbered from 1 to N, and you should build som ...

  8. Constructing Roads In JGShining's Kingdom(HDU1025)(LCS序列的变行)

    Constructing Roads In JGShining's Kingdom  HDU1025 题目主要理解要用LCS进行求解! 并且一般的求法会超时!!要用二分!!! 最后蛋疼的是输出格式的注 ...

  9. 【CodeForces 567E】President and Roads(最短路)

    Description Berland has n cities, the capital is located in city s, and the historic home town of th ...

随机推荐

  1. ref 与 $refs 如何关联

    先问大家一个简单的问题: 还有人记得 jquery 里面的 data 方法是如何让 DOM 节点绑定对应的数据对象的吗 有时候我们做节点关联设计的思路其实有一点类似,但是在 vue 里面多了很多概念, ...

  2. POJ3376 Finding Palindromes —— 扩展KMP + Trie树

    题目链接:https://vjudge.net/problem/POJ-3376 Finding Palindromes Time Limit: 10000MS   Memory Limit: 262 ...

  3. POJ3126 Prime Path —— BFS + 素数表

    题目链接:http://poj.org/problem?id=3126 Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  4. WinDbg 在64位系统下转储32位进程

    在64位系统下,首先要判断进程是32位,还是64位 在Win8之前,进程名后带星号(*)则是32位进程.但Win8.1后,则不显示星号.需要选出“平台”列,来确认32位,还是64位. 在64位系统下的 ...

  5. JAVA MAIL基本功能

    1. [代码][Java]代码package emailrobot; import java.io.*;import java.text.*;import java.util.*;import jav ...

  6. lovelygallery_popup(卡哇依相册)

    /*************************** 相册 ***************************/LovelyGallery 功能特点:超过200个令人惊叹的3D&2D硬 ...

  7. 在Service里调用AlertDialog

    用常规的方法在AlertDialog的时候,会报错,大意是「can not add window in this view」. 原因是Service是没有界面的,只有Activity才能添加界面. 解 ...

  8. [Selenium] Android HTML5 中 Web Storage

    在 HTML5 中,Web Storage 这个新特性可让用户将数据存储在本地的浏览器中.在早期的浏览器中可通过 cookies 来完成这个任务,但 Web Storage 会更加安全和高效,且 We ...

  9. apple-touch-startup-image 制作iphone web应用程序的启动画面

    为ipad制作web应用程序的启动画面时发现个问题,只能显示竖屏图,横屏图出不来,如下: 首先页面头部里要加入(这个是APP启动画面图片,如果不设置,启动画面就是白屏,图片像素就是手机全屏的像素) & ...

  10. python __builtins__ slice类 (62)

    62.'slice', 对序列化类型数据切片,返回一个新的对象. class slice(object) | slice(stop) | slice(start, stop[, step]) | | ...