POJ 1062 昂贵的聘礼 (最短路 Dijkstra)

昂贵的聘礼
 

大意:中文题

思路:每个物品看成一个节点,酋长的允诺也看作一个物品, 如果一个物品加上金币可以交换另一个物品,则这两个节点之间有边,权值为金币数,求第一个节点到所有节点的最短路。因为有等级限制,所以枚举每个点作为最低等级,选取符合所有符合等级限制的点。

PS:参考的别人的博客,理解的不是很透彻,有些地方没想明白,后面还是要复习一下。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #define INF 0x7FFFFFFF
 5 
 6 int N, M;
 7 ///物品i在有t号替代品的情况下的优惠价Map[i][t],当t=0时说明i无替代品,此时为原价
 8 int Map[110][110]; 
 9 int dis[110]; ///最初的源点0到任意点i的最初距离(权值),相当于每个物品的原价
10 int level[110];
11 int x[110];
12 bool vis[110];
13 
14 int Dijkstra()
15 {
16     int p;
17     int Min_d;
18     for(int i = 1; i <= N; i++)
19     {
20         ///假设最初的源点就是0点,初始化最初源点到各点的权值dis[i]
21         dis[i] = Map[0][i];  
22     }
23     for(int i = 1; i <= N; i++)
24     {
25         p = 0;
26         Min_d = INF;
27         for(int j = 1; j <= N; j++)
28         {
29             if(!vis[j] && Min_d >dis[j])
30             {
31                 Min_d = dis[j];
32                 p = j;
33             }
34         }
35         if(!p)
36         {
37             break;
38         }
39         vis[p] = true;
40         for(int j = 1; j <= N; j++)
41         {
42             ///把未访问但与新源点连通的点进行松弛 
43             if(!vis[j] && Map[p][j] > 0 &&dis[j] > dis[p]+Map[p][j])
44             {
45                 dis[j] = dis[p]+Map[p][j];
46             }
47         }
48     }
49     ///返回当前次交易后目标点1在等级level[i]约束下的最短距离
50     return dis[1];  
51 }
52 
53 void Solve()
54 {
55     memset(Map, 0, sizeof(Map));
56     memset(level, 0, sizeof(level));
57     memset(vis, false, sizeof(vis));
58     memset(dis, INF, sizeof(dis));
59     scanf("%d%d", &M, &N);
60     for(int i = 1; i <= N; i++)
61     {
62         ///Map[0][i]为物品i无替代品时的原价 
63         scanf("%d%d%d", &Map[0][i], &level[i], &x[i]);
64         for(int j = 1; j <= x[i]; j++)
65         {
66             int t, u;
67             scanf("%d%d", &t, &u);
68             Map[t][i] = u;
69         }
70     }
71     int Max_level;
72     int Min_price = INF;
73     for(int i = 1; i <= N; i++)
74     {
75         Max_level = level[i];///把当前物品的等级暂时看做最高等级
76         for(int j = 1; j <= N; j++)
77         {
78             if(level[j] > Max_level || Max_level-level[j] > M)
79                 vis[j] = true;
80             else
81                 vis[j] = false;
82         }
83         int t = Dijkstra();
84         if(Min_price > t)
85             Min_price = t;
86     }
87     printf("%d
", Min_price);
88 }
89 
90 int main()
91 {
92     Solve();
93 
94     return 0;
95 }
昂贵的聘礼
原文地址:https://www.cnblogs.com/Silence-AC/p/3525256.html