题目链接:https://vjudge.net/problem/POJ-1062
如图,我们可以把交换的情况,抽象为一个有向图,
先抛去等级限制,那么就是一个最短路,从①出发,到达其他点的最短路中
最短的那个就是我们需要的答案了。
当然松弛条件变成了 dis[now] - pos[now].w + w(now->to) + pos[to].w < dis[to],
这里,如果我们走了一条边,那么原来的最后加进去的物品的价格一定会发生改变,那么我们把原来的物品价格减去,
改成交换后的价格,然后要加上我们买to的那个物品的价格,然后与dis[to]比较。
等级限制,就是说你在交换物品的路上,你交换物品的所有商人集合记为P,某人商人记为px,
∀pi , pj∈P, abs(pi.level - pj.level) <= L.那么我们需要记录你一路上商人的等级,当然,我们只需要考虑极端情况就好了,
记录一个最低等级,一个最高等级,如果这两个满足,那么其他商人都会满足。代码会有解释。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #include <stack> 7 #include <string> 8 #include <map> 9 #include <cmath> 10 #include <iomanip> 11 using namespace std; 12 13 typedef long long LL; 14 #define inf 1e9 15 #define rep(i,j,k) for(int i = (j); i <= (k); i++) 16 #define rep__(i,j,k) for(int i = (j); i < (k); i++) 17 #define per(i,j,k) for(int i = (j); i >= (k); i--) 18 #define per__(i,j,k) for(int i = (j); i > (k); i--) 19 20 const int N = 110; 21 int head[N]; 22 bool vis[N]; 23 int dis[N]; 24 int cnt; 25 int L,n; 26 27 struct Pos{ 28 int w; 29 int level; 30 }pos[N]; 31 32 struct Edge{ 33 int to; 34 int w; 35 int next; 36 }e[(int)1e7]; 37 38 struct node{ 39 int loc;//当前位置 40 int level_max;//之前的最高等级 41 int level_min;//最浅的最低等级 42 int dis;//距离 43 bool friend operator< (const node& a,const node& b){ 44 return a.dis > b.dis; 45 } 46 }; 47 48 priority_queue<node> que; 49 50 void add(int u,int v,int w){ 51 e[cnt].to = v; 52 e[cnt].w = w; 53 e[cnt].next = head[u]; 54 head[u] = cnt++; 55 } 56 57 //我们要交换的商人 与之前的最高和最低等级是否满足等级限制 58 inline bool check_loc(node& now,int to){ 59 return abs(now.level_max - pos[to].level) <= L && abs(now.level_min - pos[to].level) <= L; 60 } 61 62 void dijkstra(){ 63 64 rep(i,1,n) dis[i] = inf; 65 dis[1] = pos[1].w; 66 que.push(node{1, pos[1].level, pos[1].level, dis[1]}); 67 68 node now; 69 int to,w; 70 while(!que.empty()){ 71 72 now = que.top(); 73 que.pop(); 74 if(vis[now.loc]) continue; 75 vis[now.loc] = true; 76 77 for(int o = head[now.loc]; ~o; o = e[o].next){ 78 to = e[o].to; 79 w = e[o].w; 80 81 if(dis[now.loc] - pos[now.loc].w + w + pos[to].w < dis[to] && check_loc(now,to)){ 82 dis[to] = dis[now.loc] - pos[now.loc].w + w + pos[to].w; 83 //更新遇到的最高等级和最低等级 84 que.push(node{to, min(now.level_min, pos[to].level), max(now.level_max, pos[to].level),
dis[to]}); 85 } 86 } 87 } 88 89 int ans = inf; 90 rep(i,1,n) ans = min(ans,dis[i]); 91 cout << ans << endl; 92 } 93 94 int main(){ 95 96 scanf("%d%d",&L,&n); 97 98 rep(i,1,n) head[i] = -1; 99 cnt = 0; 100 int tot,v,w; 101 rep(u,1,n){ 102 scanf("%d%d%d",&pos[u].w,&pos[u].level,&tot); 103 rep(j,1,tot){ 104 scanf("%d%d",&v,&w); 105 add(u,v,w); 106 } 107 } 108 109 dijkstra(); 110 111 getchar(); getchar(); 112 return 0; 113 }