剛剛學dijkstra算法,臥槽痛苦的幹了一下午這個題,從開始學,到模仿別人的代碼,到改代碼的bug等等一系列的事情。
終於感覺有點對這個算法入門了哈哈。
題目概述:
題目是說有一個探險家想要娶酋長的女兒,但是原始部落嘛就需要聘禮,然後幸好的是這個金幣可以由另一些不值金幣這些錢的貨物抵價,那麼我們的探險家先生就拜託我們算一算自己最少花多少錢才能娶回酋長的女兒。然後這個部落的蛋疼之處就在於等級觀念,等級差了很多的人是不能直接或者間接互相交易的。
等級限制,哪些物品能夠抵價,數據範圍請移步:
http://poj.org/problem?id=1062
算法思想:
每一個貨物模型成一個端點,端點的性質有等級,可替代物,以及自身價格。
每一個替代方式模型成一條邊,邊的性質爲花多少錢。
這道題的路徑就相當於是從最初的位置一直往下搜索,總共花的錢應該是所有路徑的錢加上最後一個結點自身的價值嗯就這樣。
然後關於等級限制的條件,用枚舉法,比如說酋長等級是4,等級限制是2,那麼我們就要取等級爲[2,4],[3,5],[4,6]的三個區間,每一個區間實際上對應着一副子圖,對子圖進行搜索就好了。
剩餘的部分就是dijkstra的實現了。
代碼部分:
#include <iostream> #include <string.h> using namespace std; int m, n, level_limit; int w[117][117]; int value[117], level[117], dis[117], replace_num; bool vis[117], satis_level[117]; int INF = 100000000; int dijkstra() { int mini_cost = INF; memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i++){ dis[i] = INF; } dis[1] = 0; for (int i = 1; i <= n; i++){ int x = 1; int min = INF; for (int j = 1; j <= n; j++){ if (!vis[j] && satis_level[j] && dis[j] <= min) { x = j; min = dis[j]; } } vis[x] = 1; for (int j = 1; j <= n; j++){ if (satis_level[j]) { dis[j] = dis[j] > (dis[x] + w[x][j]) ? (dis[x] + w[x][j]) : dis[j]; } } } for (int i = 1; i <= n; i++) { dis[i] = dis[i] + value[i]; mini_cost = dis[i] < mini_cost ? dis[i] : mini_cost; } return mini_cost; } int main() { cin >> m >> n; level_limit = m; // initialization of matri x for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (i == j) w[i][j] = 0; else w[i][j] = INF; } } // initialize input for (int i = 1; i <= n; i++){ cin >> value[i] >> level[i] >> replace_num; for (int j = 1; j <= replace_num; j++){ int y, value; cin >> y >> value; w[i][y] = value; } } int King_level = level[1]; int res = INF; for (int i = 0; i <= level_limit; i++){ memset(satis_level, 0, sizeof(satis_level)); for (int j = 1; j <= n; j++){ if (level[j] >= King_level - level_limit + i && level[j] <= King_level + i){ satis_level[j] = true; } } res = res > dijkstra() ? dijkstra() : res; } cout << res << endl; return 0; }