您的位置:首页 > 其它

POJ1724 价格合适的最短路(广搜BFS)

2012-12-09 21:31 309 查看
有编号为1-N的城市,这些城市之间存在一些单向路径,通过某条路径需要支付与路径长度一样的金币。BOB要从城市1到城市N,但他的金币数是有限的,现在要求找出从第1个城市到第N个城市的一条路径,既满足BOB支付得起路费,又满足总路径长度最小。

有点类似最短路,但因为有两个约束条件,所以说成广搜更加合适。维护一个优先队列,队列中存放的状态包括到达某个点剩下的金币和走过的路径长度,其中剩下的金币数必须为非负,队头元素是路径最小的。可以看出优先队列中存放的是合法的状态。但状态数目太多,无法全部考虑,因此需要加剪枝条件。可以为每个点存放两种状态,第一种是到达当前点走过的路径长度最小,另一种是到达当前点剩下的金币数最多。对于一个新状态,如果它可以更新以上两种状态之一或全部,则把该状态入队,否则不入队,因为比它更优的状态已经入过队了。最后的答案其实就是最后一个点的路径最短的状态。输出该最短的路径即可。

#include <iostream>
#include <cstdio>
#include <climits>
#include <algorithm>
#include <queue>
using namespace std;

const int N = 105;
const int E = 10005;
const int MAX = 0xfffffff;

struct Edge
{
int pnt;
int dis;
int cost;
int next;
};
Edge edge[E];
int neigh
;
int cur;
int n, m, e;
int ans;
int dis1
, coin1
;	//距离最小的状态
int dis2
, coin2
;	//金币最多的状态

struct Qnode
{
int pnt;
int dis;
int coin;
Qnode(int _pnt, int _dis, int _coin): pnt(_pnt), dis(_dis), coin(_coin){}
bool operator < (const Qnode& node) const
{
return dis > node.dis;
}
};

void init()
{
cur = 0;
for (int i = 0; i < n; ++i) neigh[i] = -1;
}

void bfs()
{
ans = MAX;
for (int i = 0; i < n; ++i)
{
dis1[i] = MAX;
dis2[i] = MAX;
coin1[i] = -1;
coin2[i] = -1;
}
priority_queue<Qnode> pq;
Qnode node(0, 0, m);
int pnt, te, dis, coin;
bool b1, b2;
pq.push(node);
while (!pq.empty())
{
node = pq.top();
pq.pop();
te = neigh[node.pnt];
while (te != -1)
{
pnt = edge[te].pnt;
if (node.coin - edge[te].cost >= 0)
{
if (pnt == n - 1 && node.dis + edge[te].dis < ans) ans = node.dis + edge[te].dis;
else if (pnt < n - 1)
{
dis = node.dis + edge[te].dis;
coin = node.coin - edge[te].cost;
b1 = b2 = false;
if (coin > coin2[pnt] || coin == coin2[pnt] && dis < dis2[pnt])
{
b1 = true;
coin2[pnt] = coin;
dis2[pnt] = dis;
}
if (dis < dis1[pnt] || dis == dis1[pnt] && coin > coin1[pnt])
{
b2 = true;
coin1[pnt] = coin;
dis1[pnt] = dis;
}
if (b1 || b2)
pq.push(Qnode(pnt, dis, coin));
}
}
te = edge[te].next;
}
}
}

int main()
{
int beg, end, dis, cost;
scanf("%d%d%d", &m, &n, &e);
init();
for (int i = 0; i < e; ++i)
{
scanf("%d%d%d%d", &beg, &end, &dis, &cost);
--beg;
--end;
edge[cur].pnt = end;
edge[cur].dis = dis;
edge[cur].cost = cost;
edge[cur].next = neigh[beg];
neigh[beg] = cur;
++cur;
}
bfs();
if (ans == MAX) ans = -1;
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: