这道题对于最短路来说没什么难的,难点在于等级差问题,不过好在数据集不大可以枚举枚举最低等级,在进行球最短路
详细解释见代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF 100000000
using namespace std;
int map[105][105];//记录路径
int dis[105];//记录最短路径
int leve[105];//记录等级
int mark[105];//判断物品是否合法
int maxleve;//最大等级差
int n;
int solve()//dijkstra
{
for(int i=1;i<=n;i++) dis[i]=INF;
dis[0]=0;//以0作为起点
int x;
while(1)
{
x=-1;
for(int i=0;i<=n;i++)
{
if(mark[i]==0&&(x==-1||dis[i]<dis[x])) x=i;
}
if(x==-1) break;
mark[x]=1;
for(int i=0;i<=n;i++)
{
if(mark[i]==0&&dis[i]>dis[x]+map[x][i])
{
dis[i]=dis[x]+map[x][i];
}
}
}
return dis[1];
}
int main()
{
int num;
int t1,t2;
int ans;
while(scanf("%d%d",&maxleve,&n)!=EOF)
{
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
map[i][j]=INF;
}
}
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&map[0][i],&leve[i],&num);
for(int j=1;j<=num;j++)
{
scanf("%d%d",&t1,&t2);
map[t1][i]=t2;
}
}
ans=INF;
int lv;
for(int i=1;i<=n;i++)//枚举每次dijkstra的合法点
{
int temp;
memset(mark,0,sizeof(mark));
lv=leve[i];
for(int j=1;j<=n;j++)
{
if(leve[j]<lv||leve[j]>lv+maxleve)
{
mark[j]=1;
}
}
temp=solve();
ans=min(ans,temp);
}
printf("%d\n",ans);
}
return 0;
}