题意
额,直接看题目吧,反正也是中文题,不好用几句话表述清楚~~~
题目链接
解题思路
因为等级差距不能间接交易,所以每个交易的等级都在一个区间内,这个区间必须包含大祭司的等级,可以把区间枚举,设大祭司等级为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;
}