题意:
在一个有向图中,每条边对应有其有长度和过路费,现在手握K元..要从1点走向N点...问过路费总和不大于K的最短路径长度是多少.
题解:
首先要注意几个细节: 1、题目给出的是有向图
2、两点间可能存在多条边
3、可能存在环
4、可能N点不可达
解决方法应该挺多的...我就用A*水了..和找K短路没多大区别...注意保持当前路径的费用不大于自己有的钱就ok了~
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<algorithm>
#define ll long long
#define oo 1000000007
#define pi acos(-1.0)
#define MAXN 105
using namespace std;
struct node
{
int x,toll,g,h;
bool operator <(node a) const
{
return a.g+a.h<g+h;
}
};
struct LINE
{
int y,t,l,next;
}line[MAXN*MAXN],line1[MAXN*MAXN];
int K,N,dis[MAXN],num[MAXN],_next[MAXN],_next1[MAXN];
priority_queue<node> Astarqueue;
queue<int> SPFAqueue;
bool inqueue[MAXN];
void addline(int x,int y,int l,int t,int m)
{
line[m].next=_next[x], _next[x]=m;
line[m].y=y,line[m].l=l,line[m].t=t;
}
void addline1(int x,int y,int l,int t,int m)
{
line1[m].next=_next1[x], _next1[x]=m;
line1[m].y=y,line1[m].l=l,line1[m].t=t;
}
void SPFA()
{
int h,k;
memset(inqueue,false,sizeof(inqueue));
while (!SPFAqueue.empty()) SPFAqueue.pop();
memset(dis,-1,sizeof(dis));
SPFAqueue.push(N);
dis[N]=0;
while (!SPFAqueue.empty())
{
h=SPFAqueue.front();
SPFAqueue.pop();
inqueue[h]=false;
k=_next1[h];
while (k)
{
if (dis[line1[k].y]==-1 || dis[line1[k].y]>line1[k].l+dis[h])
{
dis[line1[k].y]=line1[k].l+dis[h];
if (!inqueue[line1[k].y])
{
inqueue[line1[k].y]=true;
SPFAqueue.push(line1[k].y);
}
}
k=line1[k].next;
}
}
return;
}
int Astar()
{
int k;
node h,p;
while (!Astarqueue.empty()) Astarqueue.pop();
memset(num,0,sizeof(num));
h.x=1,h.g=0,h.h=dis[h.x],h.toll=0;
Astarqueue.push(h);
while (!Astarqueue.empty())
{
h=Astarqueue.top();
Astarqueue.pop();
if (h.x==N) break;
num[h.x]++;
if (num[h.x]>2*N) break;
k=_next[h.x];
while (k)
{
if (dis[line[k].y]!=-1 && line[k].t+h.toll<=K)
{
p.toll=line[k].t+h.toll;
p.x=line[k].y,p.h=dis[p.x],p.g=h.g+line[k].l;
Astarqueue.push(p);
}
k=line[k].next;
}
}
if (h.x!=N) return -1;
return h.g;
}
int main()
{
int M,i,num;
scanf("%d%d%d",&K,&N,&M);
memset(_next,0,sizeof(_next));
memset(_next1,0,sizeof(_next1));
num=0;
while (M--)
{
int s,d,l,t;
scanf("%d%d%d%d",&s,&d,&l,&t);
addline(s,d,l,t,++num);
addline1(d,s,l,t,num);
}
SPFA();
printf("%d\n",Astar());
return 0;
}