有三个注意点:
1、酋长的地位不一定是最高的;
2、这是有向图而不是双向图;
3、酋长的地位等级为R,从酋长开始,经过的人的地位等级必在[R-m,R+m]之中,而且经过的人的地位等级的区间长度也为m。
本题可以用枚举法+dijkstra做。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
#define Min(a,b) a<b?a:b
#define Max(a,b) a>b?a:b
#define INF 999999999
#define M 105
using namespace std;
struct Point
{
int price;
int rank;
};
struct Point p[M];
int map[M][M];
bool visit[M];
int dis[M];
int m,n;
void init()
{
int i,j;
for(i=0;i<M;i++)
{
for(j=0;j<M;j++)
{
map[i][j]=INF;
// map[i][i]=0;
}
}
}
void dijkstra(int a,int b)
{
int i,j,min,flag;
memset(visit,false,sizeof(visit));
for(i=1;i<=n;i++)
{
dis[i]=INF;
if(p[i].rank<a || p[i].rank>b)
visit[i]=true;
}
dis[1]=0;
for(i=1;i<n;i++)
{
min=INF;
for(j=1;j<=n;j++)
{
if(!visit[j] && dis[j]<min)
{
min=dis[j];
flag=j;
}
}
if(min==INF)
return;
visit[flag]=true;
for(j=1;j<=n;j++)
{
if(!visit[j] && map[flag][j]+dis[flag]<dis[j])
{
dis[j]=map[flag][j]+dis[flag];
}
}
}
}
int main()
{
int i,j,k;
while(scanf("%d%d",&m,&n)!=EOF)
{
init();
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&p[i].price,&p[i].rank,&k);
for(j=1;j<=k;j++)
{
int a,d;
scanf("%d%d",&a,&d);
map[i][a]=d;
}
}
int answer=INF;
for(i=p[1].rank-m;i<=p[1].rank;i++)
{
dijkstra(i,i+m);
for(j=1;j<=n;j++)
{
if(dis[j]+p[j].price<answer)
answer=dis[j]+p[j].price;
}
}
printf("%d\n",answer);
}
return 0;
}