题意:中文题。
思路:最短路dijkstra。需要枚举可行区间。每次运行不用重复构图,只需将不符合题意的点在used数组提前赋值为1即可。
#include <stdio.h>
#include <string.h>
#define INF 0x3fffffff
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define N 105
int lev[N],g[N][N],dis[N],used[N];
int n,m,k,diff;//diff为等级差别
int dijkstra(int a,int b){
int i,j,min,res=0,now;
for(i = 0;i<=n;i++)
dis[i] = INF;
memset(used, 0, sizeof(used));
for(i = 1;i<=n;i++)
if(lev[i]<a || lev[i]>b)
used[i] = 1;
dis[0] = 0;
while(1){
min = INF;
for(j = 0;j<=n;j++)
if(!used[j] && dis[j]<min){
min = dis[j];
now = j;
}
if(min == INF)
break;
used[now] = 1;
res += min;
for(j = 1;j<=n;j++)
if(!used[j] && dis[j]>dis[now]+g[now][j])
dis[j] = dis[now]+g[now][j];
}
return dis[1];
}
int main(){
int i,j,a,b,res = INF;
scanf("%d %d",&diff,&n);
memset(lev, 0, sizeof(lev));
for(i = 0;i<=n;i++)
for(j = 0;j<=n;j++)
g[i][j] = INF;
for(i = 1;i<=n;i++){
scanf("%d %d %d",&a,&lev[i],&j);
g[0][i] = a;
while(j--){
scanf("%d %d",&a,&b);
g[a][i] = b;
}
}
for(i = max(0,lev[1]-diff);i<=lev[1];i++){
j = dijkstra(i, i+diff);
res = min(res,j);
}
printf("%d\n",res);
return 0;
}