poj 3635 BFS+优先队列

  1 /*
  2 题意:给出n个地点,每个地点的油价为pi每单位,给出m条边,每条长度为d,行走d距离的路需
  3 要d单位的油;给出一辆车的油箱容量以及起始点:s,e;问s到e最少要耗费多少钱
  4 
  5 题解:BFS+优先队列
  6 这个搜索方式比较巧妙:状态为对于当前点是走还是油+1,这样就算想到了一般人也不太敢做,
  7 毕竟看起来复杂度还是蛮高的;其中加了一个优先队列,作用是通过类似dijkstra的贪心的方法
  8 保证求出的是最值,通过vis[][]记录状态即可去除重复。
  9 */
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <queue>
 13 
 14 using namespace std;
 15 
 16 const int MAXV = 1005;
 17 const int MAXE = 30005;
 18 
 19 struct edge
 20 {
 21     int v,w,next;
 22 }E[MAXE];
 23 
 24 int EN;
 25 int head[MAXV];
 26 
 27 void insert(int u, int v, int w)
 28 {
 29     E[EN].v = v;
 30     E[EN].w = w;
 31     E[EN].next = head[u];
 32     head[u] = EN++;
 33     E[EN].v = u;
 34     E[EN].w = w;
 35     E[EN].next = head[v];
 36     head[v] = EN++;
 37 }
 38 
 39 int p[MAXV];
 40 
 41 struct node
 42 {
 43     int cost,v,oil;
 44     bool operator<(const node &t)const
 45     {
 46         return cost > t.cost;
 47     }
 48 };
 49 
 50 bool vis[105][MAXV];
 51 
 52 int bfs(int c, int s, int e)
 53 {
 54     memset(vis,false,sizeof(vis));
 55     priority_queue<node> Q;
 56     node start;
 57     start.cost = 0;
 58     start.oil = 0;
 59     start.v = s;
 60     Q.push(start);
 61     while (!Q.empty())
 62     {
 63         node now = Q.top();
 64         Q.pop();
 65         if (now.v == e)
 66             return now.cost;
 67 
 68         vis[now.oil][now.v] = true;
 69 
 70         if (now.oil < c && !vis[now.oil+1][now.v])
 71         {
 72             now.oil++;
 73             now.cost += p[now.v];
 74             Q.push(now);
 75             now.oil--;
 76             now.cost -= p[now.v];
 77         }
 78 
 79         for(int i=head[now.v]; i!=-1; i=E[i].next)
 80         {
 81             if (now.oil >= E[i].w && !vis[now.oil-E[i].w][E[i].v])
 82             {
 83                 node tmp = now;
 84                 tmp.oil -= E[i].w;
 85                 tmp.v = E[i].v;
 86                 Q.push(tmp);
 87             }
 88         }
 89     }
 90     return -1;
 91 }
 92 
 93 int main(void)
 94 {
 95     int n,m;
 96     while (~scanf("%d%d",&n,&m))
 97     {
 98         EN = 0;
 99         memset(head,-1,sizeof(head));
100         for(int i=0; i<n; i++)
101             scanf("%d",&p[i]);
102         for(int i=0; i<m; i++)
103         {
104             int u,v,d;
105             scanf("%d%d%d",&u,&v,&d);
106             insert(u,v,d);
107         }
108 
109         int q;
110         scanf("%d",&q);
111         while (q--)
112         {
113             int s,e,c;
114             scanf("%d%d%d",&c,&s,&e);
115             int ans = bfs(c,s,e);
116             if (ans < 0)
117                 printf("impossible\n");
118             else
119                 printf("%d\n",ans);
120         }
121     }
122     return 0;
123 }

 

转载于:https://www.cnblogs.com/toufu/p/3700330.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值