Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10751 | Accepted: 3952 |
Description
Input
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题意:给出N个城市,然后给出M条单向路,以及每条路的距离和花费,问一个人有K coins,在不超出其money的情况下从城市1到城市n最短的路径是多少,首先可能会想到这是一道二级最短路问题,就是尽量让花费最小,然后让花费最小的基础上让距离最短,但是对于这道题目来说有bug,假如算出的最小花费是cost<k
其对应的最短路是dis[n],可能会存在这样一种情况,还存一种花费cost1,满足cost<cost1<=k,最短路dis1[n]<dis[n];所以不能用这种方法;
所以这道题目要用上优先队列,就是让当到达某个点的时候此时的花费<=k然后就把该点入队,某个点可能会反复入队,出队,然后优先队列保证的是当花费不超过k的情况下优先让距离最近的点出队,然后反复进行,就避免了上述的问题
程序;
#include"stdio.h" #include"string.h" #include"iostream" #include"map" #include"string" #include"queue" #include"stdlib.h" #include"math.h" #define M 109 #define eps 1e-10 #define inf 1000000000 #define mod 1000000000 using namespace std; struct st { int u,v,w,time,next; }edge[M*M*2]; int t,head[M],use[M],dis[M],time[M],k; void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w,int time) { edge[t].u=u; edge[t].v=v; edge[t].w=w; edge[t].time=time; edge[t].next=head[u]; head[u]=t++; } struct node { int id,dis,time; friend bool operator<(node a,node b) { if(a.dis==b.dis) return a.time>b.time; return a.dis>b.dis; } }; int spfa(int S,int n) { int i; priority_queue<node>q; node u; u.id=S; u.dis=u.time=0; q.push(u); while(!q.empty()) { node u=q.top(); q.pop(); if(u.id==n) return u.dis; for(i=head[u.id];i!=-1;i=edge[i].next) { node v; v.id=edge[i].v; if(u.time+edge[i].time<=k) { v.dis=u.dis+edge[i].w; v.time=u.time+edge[i].time; q.push(v); } } } return -1; } int main() { int n,m; while(scanf("%d",&k)!=-1) { scanf("%d%d",&n,&m); init(); while(m--) { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); add(a,b,c,d); } int ans=spfa(1,n); printf("%d\n",ans); } return 0; }