题意
额,直接看题目吧,反正也是中文题,不好用几句话表述清楚~~~
题目链接
解题思路
因为等级差距不能间接交易,所以每个交易的等级都在一个区间内,这个区间必须包含大祭司的等级,可以把区间枚举,设大祭司等级为L,则需要从[L-M,L],一直枚举到[L,L+M],保证所有交易的点的等级都在这个区间内就可以了,然后在进行最短路处理,进行最短路的过程中,先不考虑直接购买物品的价值,直接全部走兑换的形式,然后把得到的数组加上直接购买物品的价值,从中找到最小值就是答案。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include<vector> #include<algorithm> #include<cstdio> #include<iostream> #include<set> #include<cstring> #include<map> #include<cmath> #include<queue> using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<int,pii> PII; const int maxn = 1e4+5; struct Node { int val,level; int X; vector<pii> vp; }; struct Edge { int from,to,val; }; Node L[maxn]; vector<Edge> G[maxn]; int dis[maxn]; bool vis[maxn]; int N,M;
int dijkstra() { memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); priority_queue<pii,vector<pii>,greater<pii> > Q; dis[1] = 0; Q.push(pii(dis[1],1)); while(!Q.empty()){ pii t = Q.top(); Q.pop(); int d = t.first; int u = t.second; for(int i=0;i<G[u].size();i++){ Edge e = G[u][i]; if(e.val + d < dis[e.to]){ dis[e.to] = e.val + d; Q.push(pii(dis[e.to],e.to)); } } } int ans = 1<<30; for(int i=1;i<=N;i++){ dis[i] += L[i].val; ans = min(ans,dis[i]); } return ans; }
int main(int argc, char const *argv[]) { cin >> M >> N; int a,b; for(int i=1;i<=N;i++){ cin >> L[i].val >> L[i].level >> L[i].X; for(int j=0;j<L[i].X;j++){ cin >> a >> b; L[i].vp.push_back(pii(a,b)); } } Edge e; int left = max(0,L[1].level-M), right = left + M; int ans = 1<<30; while(left <= L[1].level){ for(int i=0;i<=N;i++){ G[i].clear(); } for(int i=1;i<=N;i++){ for(int j=0;j<L[i].X;j++){ int next = L[i].vp[j].first; if (L[next].level >= left && L[next].level <= right) { e.from = i; e.to = next; e.val = L[i].vp[j].second; G[e.from].push_back(e); } } } left++,right++; int te = dijkstra(); ans = min(ans,te); } cout << ans << endl;
return 0; }
|