这道题和我上午做的poj2253有点类似,就是多了一个LEVEL.枚举+dijkstral.
在最短路径上两点的level差值不超过M,因为1点是最短路的起点所以一定存在在最短路径中则有【lenel-m,level+m】之间。但是要保证路径中的两点不超过M,所以枚举[level-m,level],[level-m+1,level+1]......[level,level+m].
代码:
#include<iostream>
#define MAX 2000000000
using namespace std;
int dis[1001],value[1001],used[1001],lev[1001];
int map[1001][1001];
int m,n;
int minp=MAX;
int min(int a,int b)
{
if(a>b) return b;
else return a;
}
void dij(int f,int t)
{
memset(used,false,sizeof(used));
for(int i=1;i<=n; i++)
if((lev[i] < f) || (lev[i] > t))
{
used[i] = true;
}
for(int i=1;i <=n;i++)
dis[i]=MAX;
dis[1] = 0;
for(int k=1;k<=n;k++)
{
int mp=MAX;
int m = 0;
for(int i = 1; i<=n; i++)
{
if((!used[i])&&(dis[i]<mp))
{
mp = dis[i];
m = i;
}
}
if(m == 0) break;
used[m] = true;
for(int i=1;i<=n;i++)
{
if(!used[i] && (mp + map[m][i]) < dis[i])
{
dis[i] = mp + map[m][i];
}
}
}
}
int main()
{
int i,j,t,v,x;
scanf("%d%d",&m,&n);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
map[i][j] = MAX;
}
for(int i=1;i<=n;i++)
{
int x,t,v;
scanf("%d%d%d",&value[i],&lev[i],&x);
for(int j=1; j<=x; j++)
{
scanf("%d%d",&t,&v);
map[i][t] = min( map[i][t],v );
}
}
for(i=lev[1]-m;i<=lev[1];i++)
{
dij(i,i+m);
for(int j=1;j<=n;j++)
minp=min(minp,dis[j]+value[j]);
}
cout<<minp<<endl;
system("pause");
return 0;
}