昂贵的聘礼 POJ - 1062
考察:最短路+枚举
错误思路:
枚举所有点作为起点,看所能更新到1点的最短路.返回的dist[1]即为答案.
此思路错在等级处理.如果以pos[1]-m<=k<=pos[1]+m,那么交易途中的最高点和最低点就无法更新.如果在交易途中更新最高点和最低点,那么走错路的时候就不能回溯
参考了大佬的正确思路:
设探险家起始点为0,他到达所有物品的距离就是所有物品的原始价格.设pos[1] = k
同样是枚举,但不是枚举所有点,而是枚举等级范围,交易成功的等级范围一定是在[k-m,k],[k-m+1,k+1],[k-m+2,k+2]....最后到[k,k+m]
每个都进行spfa算法即可
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <queue> 5 #include <cstdio> 6 using namespace std; 7 const int N = 110; 8 int g[N][N],dist[N],m,n,mins = 0x3f3f3f3f,h[N]; 9 bool st[N]; 10 int spfa(int l,int r) 11 { 12 memset(dist,0x3f,sizeof dist); 13 dist[0] = 0; 14 queue<int> q; 15 st[0] = 1; 16 q.push(0); 17 while(q.size()) 18 { 19 int t = q.front(); 20 st[t] = 0; 21 q.pop(); 22 for(int i=1;i<=n;i++) 23 { 24 if(dist[i]>dist[t]+g[t][i]&&h[i]>=l&&h[i]<=r) 25 { 26 dist[i] = dist[t]+g[t][i]; 27 if(!st[i]) q.push(i),st[i] = 1; 28 } 29 } 30 } 31 return dist[1]; 32 } 33 int main() 34 { 35 // freopen("in.txt","r",stdin); 36 scanf("%d%d",&m,&n); 37 for(int i=1;i<=n;i++) 38 for(int j=1;j<=n;j++) 39 if(i==j) continue; 40 else g[i][j] = 0x3f3f3f3f; 41 for(int i=1;i<=n;i++) 42 { 43 int t; 44 scanf("%d%d%d",&g[0][i],&h[i],&t); 45 while(t--) 46 { 47 int id,x; scanf("%d%d",&id,&x); 48 g[id][i] = x; 49 } 50 } 51 for(int i=h[1]-m;i<=h[1];i++) mins = min(spfa(i,i+m),mins); 52 printf("%d\n",mins); 53 return 0; 54 }