这是道中文题,意思应该好理解。如果可以用物品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;
}

posted on 2011-04-08 15:51  海浪涛天  阅读(273)  评论(0编辑  收藏  举报