思路:以物品為結點,物品之間的優惠價格為邊權值建圖,酋長10000金幣當做0號結點,題意就是求圖中各結點到0號結點的最短路長度,再加上終點處物品的價值,恰好就是探險家經過這個物品買賣途徑所需要付出的金錢。用dijkstra演算法求出單源最短路徑,從各個結點的最短路徑中選出最短的那條就是答案。基本還是經典最短路問題,但做了一點小小變形主要是:
1 有結點等級限制,需要枚舉等級
2 把終點的物品價值計入最短路徑中去,並且找最小的最短路徑輸出
3 要注意是單向圖,即物品替換關係是單向的
Source Code
| Problem: 1062 |
|
User: yangliuACMer |
| Memory: 300K |
|
Time: 32MS |
| Language: C++ |
|
Result: Accepted |
#include <iostream>#define MAXN 102#define inf 100000000typedef int elem_t;using namespace std;struct Thing{int val;//該物品價值int level;//該物品主人等級int replacen;//替換品數量} things[MAXN];int m,n,nonum,noval,s,mat[MAXN][MAXN],dist[MAXN],lev[MAXN],levn;int i,j,p,k;int dijkstra(int n,elem_t mat[][MAXN],int s){int v[MAXN], maxlev, minlev;int ans = things[0].val;//枚舉等級for(p = 0; p < levn; p++){ maxlev = lev[p]; minlev = lev[p]-m; if(things[0].level < minlev || things[0].level > maxlev) continue;for (i = 0 ;i < n ;i++)dist[i] = inf,v[i] = 0;for (dist[s] = 0,j = 0; j < n; j++){for (k = -1,i = 0; i < n; i++)if (!v[i] && (k == -1|| dist[i] < dist[k])&&(things[i].level >= minlev && things[i].level <= maxlev))k=i;for (v[k] = 1,i = 0 ;i < n; i++)if (!v[i] && dist[k] + mat[k][i] < dist[i] && (things[i].level >= minlev && things[i].level <= maxlev))dist[i] = dist[k] + mat[k][i];}//把終點的val計入最短路徑中去,並且找最小的最短路徑輸出for(j=0; j<n; j++) dist[j] += things[j].val;for(j=0; j<n; j++) if(dist[j]<ans) ans = dist[j];}return ans;}int main(){//讀入資料建圖,鄰接矩陣形式cin>>m>>n;for(i = 0; i < n; i++) for(j = 0; j<n ; j++)mat[i][j] = inf;levn = 0;for(i = 0; i < n; i++){cin>>things[i].val>>things[i].level>>things[i].replacen;lev[levn++] = things[i].level;//記錄所有物品的等級for(j = 0; j < things[i].replacen; j++){cin>>nonum>>noval;mat[i][nonum-1] = noval;//注意是單向圖}}cout<<dijkstra(n,mat,0)<<endl;return 0;}