poj1062
本质就是有限制的最短路,将一路上的最大和最小等级记录,每次选取最大最小等级差在允许范围内的点加入即可,用dijkstra可以了,不要忘记最后要加入最后一个购买的物品价值(优惠价为权)
#include <stdio.h> #include <string.h> #define len 101 #define INF (1<<30) #define ABS(a) ((a)<0?(-a):(a)) #define SUB(a,b) (ABS(a-b)<=m?true:false) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) struct node { int money,loc,num; }per[len]; int map[len][len],cost[len]; int m,n,mincost,maxloc[len],minloc[len]; bool v[len]; void dij() { for(int i=0;i<=n;cost[i++]=INF); cost[1]=0; int min=INF,minnum=0; for(int k=1;k<=n;++k) { min=INF; for(int i=1;i<=n;++i) if(!v[i]&&cost[i]<min &&SUB(maxloc[i],minloc[i]))//选取是比较最大和最小 min=cost[i],minnum=i; v[minnum]=true; mincost=MIN(mincost,cost[minnum]+per[minnum].money); for(int i=1;i<=n;++i) if(!v[i]&&map[minnum][i]!=-1&&cost[minnum]+map[minnum][i]<cost[i]) { cost[i]=cost[minnum]+map[minnum][i]; maxloc[i]=MAX(maxloc[minnum],per[i].loc);//更新到达该点的路径上等级最大和最小 minloc[i]=MIN(minloc[minnum],per[i].loc); } } } int main() { while(scanf("%d %d",&m,&n)==2) { memset(map,-1,sizeof(map)); memset(v,false,sizeof(v)); for(int i=1;i<=n;++i) { scanf("%d %d %d",&per[i].money,&per[i].loc,&per[i].num); for(int j=1,p,q;j<=per[i].num;++j) { scanf("%d %d",&p,&q); map[i][p]=q; } } mincost=per[1].money; maxloc[1]=minloc[1]=per[1].loc; dij(); printf("%d\n",mincost); } return 0; }