有三个注意点:
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; }