您的位置:首页 > 其它

POJ 1724 ROADS (优先队列+最短路)

2016-11-16 21:22 387 查看
Description

N cities named with numbers 1 ... N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll that needs to be paid for the road (expressed in the number
of coins). 

Bob and Alice used to live in the city 1. After noticing that Alice was cheating in the card game they liked to play, Bob broke up with her and decided to move away - to the city N. He wants to get there as quickly as possible, but he is short on cash. 

We want to help Bob to find the shortest path from the city 1 to the city N that he can afford with the amount of money he has. 

Input

The first line of the input contains the integer K, 0 <= K <= 10000, maximum number of coins that Bob can spend on his way. 

The second line contains the integer N, 2 <= N <= 100, the total number of cities. 

The third line contains the integer R, 1 <= R <= 10000, the total number of roads. 

Each of the following R lines describes one road by specifying integers S, D, L and T separated by single blank characters : 
S is the source city, 1 <= S <= N 

D is the destination city, 1 <= D <= N 

L is the road length, 1 <= L <= 100 

T is the toll (expressed in the number of coins), 0 <= T <=100

Notice that different roads may have the same source and destination cities.

Output

The first and the only line of the output should contain the total length of the shortest path from the city 1 to the city N whose total toll is less than or equal K coins. 

If such path does not exist, only number -1 should be written to the output. 

Sample Input

5
6
7
1 2 2 3
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2


Sample Output

11


题意:你想从一个城市出发去到另一个城市,然而有很多选择,怎么走才是最好的呢 ?k  n  m 分别是你拥有的钱k,一共n个城市 ,编号1~n,n个城市之间有m条路。

     1  2  2  3 代表的是1到2有一条路,长度是2,你需要花费3元从1到2,现在问,花费不超过你所拥有钱的范围内,你可以选择的最短路是多长。

      采用的是优先队列,在队列里面把花费按从小到大排序,若花费相等,按路程从小到大排,每到一个城市判断可以走到那个城市,并且花费不大于预算,那就可以入队。

   判断一个元素能否入队,不再是看它的最短路估计值是否被更新,而是从当前点能到达的点,都可以放入队列,在优先队列中,每次取队中最短路估计值最小的元素出来去更新

   如果标号为n的点出队了,那么其实算法结束了,因为之前的状态都没有更新出更小的值,在从现在开始,哪怕再怎么更新,都不会比现在更小了,所以直接跳出,输出即可

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#define INF 0x3f3f3f
using namespace std;
int k,n,m;
int head[110];
int tot;
struct node
{
int n,d,c;
bool operator <(const node &a) const
{
if(a.d==d) return a.c<c;//按花费从小到大排,花费相同按路程从小到大排
return a.d<d;
}

};
struct edge
{
int u,v,w,c,next;
}e[10010];
void add(int u,int v, int w,int c)
{
e[tot].u=u, e[tot].v=v, e[tot].w=w, e[tot].c=c;
e[tot].next=head[u], head[u]=tot++;//数组模拟链表
}
void bfs()
{
priority_queue<node>Q;
node p,q;
p.n=1;
p.d=0;
p.c=0;
Q.push(p);
int res =INF;
while(!Q.empty())
{
p=Q.top();
Q.pop();
if(p.n==n)
{
res=p.d;
break;
}
int v,w,c;
for(int j=head[p.n];j!=-1;j=e[j].next)//按照链表依此查询
{
v=e[j].v, w=e[j].w, c=e[j].c;
if(p.c+c<=k)//花费不能大于你所有的钱
{
q.c=p.c+c;
q.d=p.d+w;
q.n=v; //从u走到v,v就相当于是一个新的起点
Q.push(q);
}
}

}
while(!Q.empty())
Q.pop();
if(res==INF) printf("-1\n");//没有找到可以在预算内到达城市n的路
else printf("%d\n",res);
}
int main()
{
int i,j;
while(~scanf("%d%d%d",&k,&n,&m))
{
memset(head,-1,sizeof(head));
tot=0;
int u,v,w,c;
for(i=0;i<m;i++)
{
scanf("%d%d%d%d",&u,&v,&w,&c);
add(u ,v, w, c);
}
bfs();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BFS 最短路