http://poj.org/problem?id=1062
每个物品看成一个节点,酋长的允诺也看作一个物品, 如果一个物品加上金币可以交换另一个物品,
则这两个节点之间有边,权值为金币数,求第一个节点到所有节点的最短路。
因为有等级限制,所以枚举每个点作为最低等级,选取符合所有符合等级限制的点。注意:酋长的等级不一定是最高的。
1 #include<stdio.h> 2 #include<string.h> 3 const int INF=1<<28; 4 const int Max=105; 5 int vis[Max],dis[Max],rank[Max]; 6 int price[Max][Max]; 7 int x[Max],N,M; 8 int Dijkstra() 9 { 10 int pos; 11 for (int i = 1; i <= N; i ++) 12 { 13 dis[i] = price[0][i];//初始化每个物品本身的价格 14 } 15 for (int i = 1; i <= N; i ++) 16 { 17 pos = 0; 18 int min = INF; 19 for (int j = 1; j <= N; j ++) 20 { 21 if (!vis[j] && dis[j] < min) 22 { 23 min = dis[j]; 24 pos = j; 25 } 26 } 27 if (pos == 0) 28 break; 29 vis[pos] = 1; 30 for (int j = 1; j <= N; j ++) 31 { 32 if (!vis[j] && price[pos][j] > 0 && dis[j] > min + price[pos][j]) 33 { 34 dis[j] = price[pos][j]+min; 35 } 36 } 37 } 38 return dis[1]; 39 } 40 void init() 41 { 42 memset(vis,0,sizeof(vis)); 43 memset(price,0,sizeof(price)); 44 memset(rank,0,sizeof(rank)); 45 memset(dis,0,sizeof(dis)); 46 47 } 48 int main() 49 { 50 scanf("%d%d",&M,&N); 51 init(); 52 int minprice = INF; 53 for (int i = 1; i <= N; i ++) 54 { 55 scanf("%d%d%d",&price[0][i],&rank[i],&x[i]); 56 for (int j = 1; j <= x[i]; j ++) 57 { 58 int num,p; 59 scanf("%d%d",&num,&p); 60 price[num][i] = p;//表示能代替i号物品的num号替代品的价格 61 } 62 } 63 for (int i = 1; i <= N; i ++) 64 { 65 int max=rank[i]; 66 for (int j = 1; j <= N; j ++) 67 { 68 if (rank[j] > max ||max - rank[j] > M)//去除不符合等级限制的点 69 vis[j] = 1; 70 else 71 vis[j] = 0; 72 } 73 int ans = Dijkstra(); 74 if (ans < minprice) 75 minprice = ans; 76 } 77 printf("%d ",minprice); 78 return 0; 79 }