昂贵的聘礼 POJ - 1062

题目链接: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 }

 

posted @ 2019-08-19 14:00  SummerMingQAQ  阅读(247)  评论(0编辑  收藏  举报