题意
额,直接看题目吧,反正也是中文题,不好用几句话表述清楚~~~
题目链接
解题思路
因为等级差距不能间接交易,所以每个交易的等级都在一个区间内,这个区间必须包含大祭司的等级,可以把区间枚举,设大祭司等级为L,则需要从[L-M,L],一直枚举到[L,L+M],保证所有交易的点的等级都在这个区间内就可以了,然后在进行最短路处理,进行最短路的过程中,先不考虑直接购买物品的价值,直接全部走兑换的形式,然后把得到的数组加上直接购买物品的价值,从中找到最小值就是答案。
AC代码
#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;
}