题解:
可以想象成无源最短路。最开始到达所有点的路程(买物品的价格)是它本身的价格。然后取出价格最小的那个,用它对其他的物品进行松弛。
关于这张图的建立:如果有物品a,物品b会降至c元,那么就建一条路a—>b=c。
松弛操作:if(权值<dis[j]-dis[p])dis[j]=dis[p]+权值
遍历所有的等级范围,求出最小值即为答案。
#include <iostream>
#include <cstdio>
#include <map>
#include <queue>
#include <stack>
#include <string.h>
#include <string>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long LL;
int m,n,t;
int a[105],b[105];
int dis[105],vis[105],mz[105][105];
int dij(int lo,int hi){
memset(vis,0,sizeof(vis));
memset(dis,125,sizeof(dis));
for(int i=1;i<=n;i++){
if(b[i]>=lo&&b[i]<=hi)
dis[i]=a[i];
else vis[i]=1;
}
for(int i=1;i<=n;i++){
int p=0;
for(int j=1;j<=n;j++){
if(!vis[j]&&dis[j]<dis[p])
p=j;
}
if(p==0) break;
vis[p]=1;
for(int j=1;j<=n;j++){
if(!vis[j]&&mz[p][j]>=0&&mz[p][j]<dis[j]-dis[p])
dis[j]=dis[p]+mz[p][j];
}
}
return dis[1];
}
int main(){
memset(mz,-1,sizeof(mz));
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i],&b[i],&t);
int u,w;
while(t--){
scanf("%d%d",&u,&w);
mz[u][i]=w;
}
}
int ans=(int)1e9;
for(int i=b[1]-m;i<=b[1];i++){
ans=min(ans,dij(i,i+m));
}
printf("%d\n",ans);
}