POJ1062昂貴的聘禮(dijkstra)


昂貴的聘禮

題目大意是說有N個物品,每個物品都有自己的價格,但同時某些物品也可以由其他的(可能不止一個)替代品,這些替代品的價格比較“優惠”,問怎么樣選取可以讓你的花費最少來購買到物品1

由於有N個物品,我們就可以把它們看作是N個點,從其他點到他的優惠關系視做邊,又因為最后總是要找到物品1,所以可以看作是從起點0,到將物品1作為終點的最小路勁。然后由於題目是說,這條路勁上不能有兩個的等級差超過M,所以我們可以枚舉最小等級,將每個點視作最小等級,這樣的話就不會掉解。

又由於我們是枚舉的最小等級,所以源點0到其他每個點的邊的權值就要賦值為那個點的價格,降等級比最小等級要大,或者差距大於M的其他點標記為不合法(也就是不可以走),然后在從合法的路勁中找出最小花費。

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<map>
 5 #include<vector>
 6 #include<set>
 7 #include<stack>
 8 #include<queue>
 9 #include<algorithm>
10 #include<stdlib.h>
11 using namespace std;
12 #define MAX(a,b) (a > b ? a : b)
13 #define MIN(a,b) (a < b ? a : b)
14 #define mem(a) memset(a,0,sizeof(a))
15 #define MAXN 105
16 #define INF 1000000007
17 
18 int Price[MAXN],Edge[MAXN][MAXN],Level[MAXN];
19 int vis[MAXN], d[MAXN];
20 int N,M,ans;
21 
22 void init()
23 {
24     mem(Price); mem(Level);
25     for(int i=0;i<=N;i++)
26     {
27         for(int j=0;j<=N;j++)
28         {
29             Edge[i][j] = INF;//初始化每條邊都是不連通的
30         }
31     }
32 }
33 
34 void read()
35 {
36     int i,j,X,T,TP;
37     for(i=1;i<=N;i++)
38     {
39         scanf("%d%d%d",&Price[i], &Level[i], &X);
40         for(j=0;j<X;j++)
41         {
42             scanf("%d %d", &T, &TP);
43             Edge[T][i] = TP;//記錄邊
44         }
45         Edge[0][i] = Price[i];
46     }
47 }
48 
49 int dijkstra()
50 {
51     for(int i=1;i<=N;i++)d[i] = Price[i];//源點0到每個點的權值賦為這個點的價格
52     for(int i=1;i<=N;i++)
53     {
54         int temp = INF,x;
55         for(int j=1;j<=N;j++)if(!vis[j] && d[j]<=temp)temp = d[x = j];
56         vis[x] = 1;
57         for(int j=1;j<=N;j++)if(d[x]+Edge[x][j] < d[j] && !vis[j])d[j] = d[x]+Edge[x][j];//要從合法的物品中選取,加上!vis[j]
58     }
59     return d[1];//這里找到的最小值是未知起點的最小值
60 }
61 
62 int main()
63 {
64     while(~scanf("%d %d", &M, &N))
65     {
66         init();
67         read();
68         ans = INF;
69         for(int i=1;i<=N;i++)
70         {
71             int minLevel = Level[i];//將目前的點視作等級最高的點
72             for(int j=1;j<=N;j++)
73             {
74                 if(Level[j] - minLevel > M || minLevel > Level[j])vis[j] = 1;//如果有比它還低的點,或者差超過M,視為不合法
75                 else vis[j] = 0;
76             }
77             int now = dijkstra();
78             ans = MIN(ans,  now);
79         }
80         printf("%d\n", ans);
81     }
82     return 0;
83 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM