思路:
输入n个结点,手动添加一个n+1结点,n+1节点到i节点的距离代表直接购买物品的花费,从j结点到k节点的距离代表物品k用j换的花费。输入数据时候判断物品的等级是否在酋长等级的【+-m】内,在的话才添加,不然就还是inf。dijkstra内更新距离时判断和之前所有添加过的点的等级与最小点等级的差是否满足条件。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
using namespace std;
int m, n;
int edges[111][111];
int rootl;
int dis[111];
bool vis[111];
map<int, int>mymap;
vector<int>vec;
void dijkstra() {memset(dis, inf, sizeof(dis));vec.clear();for (int i = 1; i <= n + 1; i++) {dis[i] = edges[n + 1][i];}vis[n + 1] = true;vec.push_back(n + 1);for (int i = 1; i <n+1; i++) {int min_ = inf;int v=-1;for (int j = 1; j <= n + 1; j++) {if (!vis[j] && min_ > dis[j]) {min_ = dis[j];v = j;}}if (v == -1)break;vis[v] = true;vec.push_back(v);for (int j = 1; j <= n + 1; j++) {if (!vis[j]) {bool fg = true;for (int k = 0; k < vec.size(); k++) {if (abs(mymap[vec[k]] - mymap[j]) > m) {fg = false;break;}}if(fg)dis[j] = min(dis[j], dis[v] + edges[v][j]);}}}cout << dis[1] << endl;
}
int main() {while (cin >> m >> n) {mymap.clear();memset(edges, inf, sizeof(edges));memset(vis, false, sizeof(vis));for (int i = 1; i <= n + 1; i++) {edges[i][i] = 0;}for (int i = 1; i <= n; i++) {int p, l, x;cin >> p >> l >> x;mymap[i] = l;if (i == 1) {rootl = l;mymap[n + 1] = l;}if (abs(rootl - l) <= m){ edges[n + 1][i] = p;}for (int j = 0; j < x; j++) {int t, v;cin >> t >> v;if (abs(rootl - l) <= m)edges[t][i] = v;}}dijkstra();}return 0;
}
- 测试数据1:
- 1 4
- 10000 3 2
- 2 8000
- 3 5000
- 1000 2 1
- 4 200
- 3000 2 1
- 4 200
- 50 2 0
- 5250
- 测试数据2:
- 1 5
- 10000 3 4
- 2 3000
- 3 2000
- 4 2000
- 5 9000
- 8000 2 3
- 3 5000
- 4 2000
- 5 7000
- 5000 1 0
- 2000 4 1
- 5 1900
- 50 1 0
- 4000
- 测试数据3:
- 3 8
- 10000 3 6
- 2 3000
- 3 2000
- 4 2000
- 5 9000
- 7 1000
- 8 5008
- 8000 2 3
- 3 5000
- 4 2000
- 5 7000
- 5000 1 1
- 6 1000
- 2000 4 1
- 5 1900
- 50 1 0
- 5000 1 1
- 7 4007
- 2000 4 1
- 5 1900
- 80 3 0
- 2950
- 测试数据4:
- 1 10
- 1324 0 0
- 1234 0 0
- 255 0 0
- 67 0 0
- 56 0 0
- 2134 0 0
- 456 0 0
- 2345 0 0
- 67 0 0
- 6436 0 0
- 1324
- 测试数据5:
- 1 4
- 10000 3 2
- 2 1
- 3 3
- 1000 2 2
- 4 1
- 3 1
- 1000 3 1
- 4 2
- 100 4 0
- 105
- 测试数据6:
- 3 5
- 10000 3 4
- 2 3000
- 3 2000
- 4 2000
- 5 9000
- 8000 2 3
- 3 5000
- 4 2000
- 5 7000
- 5000 1 0
- 2000 4 1
- 5 1900
- 50 1 0
- 3950