题意:

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. (linux)tasklet

      tasklet Tasklet的使用比较简单,只需要定义tasklet及其处理函数并将两者关联 例子: Void my_tasklet_func(unsigned long) DECLARE_TA ...

  2. dedecms专题列表页不显示标题的解决办法

    在网站专题中的标题都是比较长的,所以在调用title的时候没有使用title而是使用fulltitle的,fulltitle在其他的模型中都是可以正常使用的,也可以调用出字段,但是在专题中就没有调用出 ...

  3. SpringMVC配置环境

    一,lib目录下加入spring一般所需的jar包 二,配置web.xml <?xml version="1.0" encoding="UTF-8"?&g ...

  4. html5--6-16 CSS3中的文字与字体

    html5--6-16 CSS3中的文字与字体 中文字体包很大,少量字体的话可以有其它方法. 有字库-首页-全球第一中文web font(在线字体)服务平台.web font.webfont.在线字体 ...

  5. 15个你不可不知的cmd命令

    cmd和dos: dos是Disk Operating System 磁盘操作系统的缩写,它是个人计算机上的一类操作系统.跟Windows图像界面操作系统不同的是,dos是一种面向磁盘的操作系统,并且 ...

  6. BroadcastReceiver中调用Service

    首先是代码: package com.larry.msglighter; import android.content.BroadcastReceiver; import android.conten ...

  7. fasttext(1) -- 认识 fasttext 和 初步使用

    fastText 的 Python接口:https://github.com/salestock/fastText.py (1) fasttext 简介:FastText是Facebook开发的一款快 ...

  8. linux--memcache的安装和使用(转)

    memcache是高性能,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度.据说官方所说,其用户包括twitter.digg.flickr等,都是些互联网大腕呀.目前用memca ...

  9. 修改cocos2dx 背景颜色

    只需要在AppDelegate的设置FPS后面加入一行: glClearColor(1.0, 1.0, 1.0, 1.0); 同理如果要修改成其它颜色,只需修改里面的值即可( r, g, b, a);

  10. 数据库sql互转(oracle转mysql为例子)

    转自: https://blog.csdn.net/sinat_32366329/article/details/76402059 在PowerDesinger里找到 File -->> ...