嘛,每条边都有某两个权值K,L,要求到达某一点且使得K的总和不超过某一个值得情况下求L最小,有约束问题的最短路。
首先我的感觉是这样子约束之后最短路就没有最优子结构性质了,a~b的最短路和b~c的最短路之和不一定是a~c的最短路,因为有coin的约束。失去了最优子结构的性质Dijkstra用不上了,贪心策略解决的问题是要求满足最优子结构性质的嘛。用SPFA的话,那么在原来的松弛边的地方我们要怎么写判断条件?。。。一番思考之下,还是考虑最原始的BFS吧,不过需要用优先队列来优化,距离越小的越靠前,因此在这种情况下,一旦发现top是目标节点的话,那么答案就出来了,至于判-1?没有负边的情况下,队列里面的总体元素的距离和coin量是不断上升的,因此一旦大于了给定的coin值就不会再入队,这样下去队列总会空的。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct Node{
int v,toll,len,next;
Node(int a=0,int b=0,int c=0,int d=0):v(a),toll(b),len(c),next(d){};
}edge[10005];
struct con{
int toll,len,v;
con(int a=0,int b=0,int c=0):toll(a),len(b),v(c){};
bool operator<(const con& a)const{return len>a.len;};
}te;
priority_queue<con> q;
int sz,k,n,r,s,d,l,t,first[10005];
bool flag;
void addeage();
int main(){
while(scanf("%d",&k)!=EOF){
scanf("%d%d",&n,&r);
memset(first,-1,sizeof(int)*(n+1));
for(int i=0;i<r;++i)
scanf("%d%d%d%d",&s,&d,&l,&t),addeage();
q.push(con(0,0,1));
while(!q.empty()){
te=q.top();q.pop();
if(te.v==n){
printf("%d\n",te.len);
flag=true;
break;
}
for(int i=first[te.v];i!=-1;i=edge[i].next)
if(te.toll+edge[i].toll<=k)
q.push(con(te.toll+edge[i].toll,te.len+edge[i].len,edge[i].v));
}
if(!flag)
printf("-1\n");
while(!q.empty())q.pop();
sz=0;flag=false;
}
return 0;
}
void addeage(){
edge[sz]=Node(d,t,l,first[s]);
first[s]=sz++;
}