1. 程式人生 > >POJ-1062 昂貴的聘禮---Dijkstra+枚舉上界

POJ-1062 昂貴的聘禮---Dijkstra+枚舉上界

全部 string href str 如果 tro typedef money 距離

題目鏈接:

https://vjudge.net/problem/POJ-1062

題目大意:

中文題

思路:

1是終點,可以額外添加一個源點0,0到任意一節點的距離就是這個點的money,最終求的是d[1]最小值,但是由於有等級觀念,所以必須枚舉,每次枚舉等級的上界,如果有不符合當前枚舉的上界,就標記其不加入dijk算法中,然後跑一遍最短路,求出d[1],最終取d[1]的最小值

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6
#include<queue> 7 #include<stack> 8 #include<map> 9 #include<set> 10 #include<sstream> 11 #define MEM(a, b) memset(a, b, sizeof(a)); 12 using namespace std; 13 typedef long long ll; 14 const int maxn = 100 + 10; 15 const int INF = 0x3f3f3f3f; 16 int T, n, m, cases;//m是等級差 17
int Map[maxn][maxn]; 18 int d[maxn], v[maxn]; 19 struct node 20 { 21 int money, rank; 22 }cnt[maxn]; 23 int dijkstra() 24 { 25 for(int i = 1; i <= n; i++)d[i] = cnt[i].money;//假定的原點0,到每個點的距離就是它自己的價格 26 for(int i = 1; i <= n; i++) 27 { 28 int x = 0, m = INF; 29 for(int
i = 1; i <= n; i++)if(!v[i] && m > d[i])m = d[x = i];//找出當前在集合中的最小距離 30 if(!x)break;//已經全部標記完畢 31 v[x] = 1; 32 for(int i = 1; i <= n; i++) 33 if(!v[i])d[i] = min(d[i], d[x] + Map[x][i]);//這裏必須加上判斷條件,因為有部分物品由於等級限制沒有加入選項中 34 } 35 return d[1]; 36 } 37 int main() 38 { 39 cin >> m >> n; 40 for(int i = 1; i <= n; i++) 41 for(int j = 1; j <= n; j++)Map[i][j] = INF; 42 MEM(cnt, 0); 43 MEM(v, 0); 44 int x, a, b; 45 for(int i = 1; i <= n; i++) 46 { 47 cin >> cnt[i].money >> cnt[i].rank >> x; 48 while(x--) 49 { 50 cin >> a >> b; 51 Map[a][i] = b;//存圖,存下從a到i的路徑,這樣就可以轉化成求到點1的最短路徑 52 } 53 } 54 int ans = INF; 55 for(int i = 1; i <= n; i++) 56 { 57 int maxrank = cnt[i].rank;//枚舉rank的上界 58 for(int j = 1; j <= n; j++) 59 if(maxrank - cnt[j].rank > m || cnt[j].rank > maxrank)v[j] = 1; 60 //事先標記好不符合條件的物品,如果有等級大於當前枚舉的最大等級或者等級差超過m的標記,在dijk算法中不添加這些元素 61 else v[j] = 0; 62 ans = min(ans, dijkstra()); 63 } 64 cout<<ans<<endl; 65 return 0; 66 }

POJ-1062 昂貴的聘禮---Dijkstra+枚舉上界