昂贵的聘礼 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 }

 

posted @ 2021-01-21 21:27  acmloser  阅读(41)  评论(0编辑  收藏  举报