NYOJ 510 POJ 1062
View Code
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 }