这是道中文题,意思应该好理解。如果可以用物品n代替物品m,那么节点n和m是连接的,这样就可以转化成图的问题,然后求最短路径。用到的算法是Dijstra(),但是在处理等级和dist[]的时候比较麻烦。一开始我是把1作为开始点,然后去查找,wrong了好久。后来,到网上看大牛的博客,发现一个好方法:从其他各点开始一直找到1节点,因为只有拿到酋长的允诺才能娶到酋长的女儿。另外,等级问题可以用枚举法,假设节点1的等级是5,m的取值是3,那么只有在等级是2~5,3~6,4~7,5~8这几种情况中选择节点。
只有思路清楚、正确,代码才容易写正确。
源代码:
#include<stdio.h>
#define max 999999
#define N 102
int a,map[N][N],dist[N],m,n,b[N],x,s[N],t,v,u;
int Dijstra()
{
int i,j,p,mindis,k;
mindis=map[0][1];
for(k=b[1]-m;k<=b[1];k++)
{
for(i=1;i<=n;i++)
{
s[i]=0;
dist[i]=map[0][i];
}
for(i=1;i<n;i++)
{
p=max;
for(j=1;j<=n;j++)
if(s[j]==0&&dist[j]<p&&b[j]>=k&&b[j]<=k+m)
{
p=dist[j];
u=j;
}
s[u]=1;
for(j=1;j<=n;j++)
if(s[j]==0&&dist[u]+map[u][j]<dist[j]&&b[j]>=k&&b[j]<=k+m)
dist[j]=dist[u]+map[u][j];
}
if(dist[1]<mindis)
mindis=dist[1];
}
return mindis;
}
int main()
{
int i,j;
while(scanf("%d%d",&m,&n)!=EOF)
{
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=map[j][i]=max;
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&a,&b[i],&x);
map[0][i]=a;
while(x--)
{
scanf("%d%d",&t,&v);
map[t][i]=v;
}
}
printf("%d\n",Dijstra());
}
return 0;
}
![](https://img2024.cnblogs.com/blog/35695/202408/35695-20240826070647288-243310440.jpg)