1 /*
2 思路:
3 dijkstra变形
4 因为有等级限制
5 我们就假设 第 i 个人参加交易 以他的等级为最大等级
6 把不符合等级要求的人的 flag[i]=true(相当于这个人不参与交易 也即不在这个最短路图中)
7 这就把所有可以参加交易的人留了下来
8 price[i][j]存放的是 在有物品 i 的 情况下 的到物品 j 的优惠价格(相当于边的权值)
9
10 在应用 dijkstra时有点变形
11 此时没有明确的起点 d[i] 的初值就是 直接买 这个物品的价格
12 */
13 #include<iostream>
14 #include<cstdio>
15 #include<cstring>
16 using namespace std;
17
18 const int size = 101;
19 const int inf = 999999999;
20 int d[size];
21 int level[size];
22 int price[size][size];
23 bool flag[size];
24
25 int qmin(int x,int y)
26 {
27 return ((x)<(y))?(x):(y);
28 }
29
30 int dij(int N)
31 {
32 int i,j;
33 for(i=1;i<=N;++i)//物品的直接价格
34 d[i]=price[0][i];
35 for(i=1;i<=N;++i)
36 {
37 int mi=inf;
38 int k=0;
39 for(j=1;j<=N;++j)
40 if(!flag[j] && mi>d[j])
41 {
42 mi=d[j];
43 k=j;
44 }
45 if(!k)break;//这个很重要 因为 有些点初始时已经加入
46 flag[k]=true;
47
48 for(j=1;j<=N;++j)
49 {
50 if(!flag[j] && d[j] > d[k]+price[k][j])
51 {
52 d[j]=d[k]+price[k][j];
53 }
54 }
55 }
56 return d[1];
57 }
58
59 int main()
60 {
61 int M,N,X,i,j,a,b;
62 while(scanf("%d%d",&M,&N) && (M || N))
63 {
64 for(i=1;i<=N;++i)
65 {
66 price[i][i]=0;
67 for(j=i+1;j<=N;++j)
68 price[i][j]=price[j][i]=inf;
69 }
70 for(i=1;i<=N;++i)
71 {
72 scanf("%d%d%d",&price[0][i],&level[i],&X);
73 for(j=0;j<X;++j)
74 {
75 scanf("%d%d",&a,&b);
76 price[a][i]=b;
77 }
78 }
79
80 int maxlevel;
81 int minp=inf;
82 for(i=1;i<=N;++i)
83 {
84 maxlevel=level[i];// 以这个人的等级为最高等级相当于他参与交易
85 for(j=1;j<=N;++j)
86 if(level[j]>maxlevel || maxlevel-level[j]>M)flag[j]=true;
87 else flag[j]=false;
88 minp=qmin(minp,dij(N));
89 }
90 printf("%d\n",minp);
91 }
92 return 0;
93 }