求有限制的最短路,重点在于等级限制。处理的方法是:将一路径上的最大、最小等级记录下来,每次取最大最小等级差在允许的范围内的点加入。这只要申请几个数组就可以办到,很简单的。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=102;
const int inf=100000000;
int m,n,mincost;
bool visit[maxn];
int dist[maxn],maxl[maxn],minl[maxn],w[maxn][maxn];
struct node
{
int value;
int loc;
int num;
}point[maxn];
bool check(int a,int b)
{
if(abs(a-b)<=m)
return true;
else
return false;
}
void Dijkstra()
{
int i,j,k,minv;
for(i=1;i<=n;i++)
dist[i]=inf;
dist[1]=0;
k=1;
for(i=1;i<=n;i++)
{
minv=inf;
for(j=1;j<=n;j++)
if(dist[j]<minv && !visit[j] && check(maxl[j],minl[j]))
{
minv=dist[j];
k=j;
}
visit[k]=true; //访问完这个结点
mincost=min(mincost,point[k].value+dist[k]); //买目标结点的物品要钱
for(j=1;j<=n;j++)
if(!visit[j] && w[k][j]!=-1 && dist[k]+w[k][j]<dist[j])
{
dist[j]=dist[k]+w[k][j];
maxl[j]=max(maxl[k],point[j].loc);
minl[j]=min(minl[k],point[j].loc);
}
}
}
int main()
{
int i,j,a,b;
while(scanf("%d%d",&m,&n)!=EOF)
{
memset(w,-1,sizeof(w));
memset(visit,0,sizeof(visit));
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&point[i].value,&point[i].loc,&point[i].num);
for(j=1;j<=point[i].num;j++)
{
scanf("%d%d",&a,&b); //物品编号、价格
w[i][a]=b; //有向图的最短路径
}
}
mincost=point[1].value;
maxl[1]=point[1].loc;
minl[1]=point[1].loc;
Dijkstra();
printf("%d\n",mincost);
}
return 0;
}