• UVa11367/poj3635 Full Tank?


    读题可发现,对于每一个由地点和油量组成的二元状态,我们只有2种决策:

    1.加油。

    2.去往下一个能去的目的地。

    最开始的时候其实不知道怎么确定加油的多少。但是看看数据规模。。。直接上暴力的记忆化bfs吧!

    决策2的状态转移很好办,决策一的就暴力的让它每一次加一单位油,然后看作新状态。

    关于算法的正确性,容易证明,使用优先队列的BFS中,每个状态(或者说阶段)第一次出队时即为该状态的最小代价。

    具体在这道题中,当终点T的某个状态第一次被取出时,即为最优答案.

    (我不会说我第一次写没有用记忆化然后TLE了)

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <queue>
     4 #include <vector>
     5 #include <cstring>
     6 #include <iostream>
     7 using namespace std;
     8 const int MAXN = 1000 + 20;
     9 const int INF = 0x3f3f3f3f;
    10 
    11 int N, M, Q;
    12 int C, S, T;
    13 int cc[MAXN], d[MAXN][110];
    14 
    15 struct edge
    16 {
    17     int to, dis;
    18     edge(int v = 0, int c = 0) : to(v), dis(c) {}
    19 };
    20 
    21 vector<edge> g[MAXN];
    22 
    23 struct P
    24 {
    25     int city, fuel, cost;
    26     bool operator >(const P &x) const{
    27         return cost > x.cost;
    28     }
    29 }ans;
    30 
    31 inline bool solve()
    32 {
    33     priority_queue<P, vector<P>, greater<P> > q;
    34 
    35     d[S][0] = 0;
    36     P s;
    37     s.city = S, s.fuel = 0, s.cost = 0;
    38     q.push(s);
    39     while(!q.empty())
    40     {
    41         P p = q.top(); q.pop();
    42         if(p.city == T)
    43         {
    44             ans = p; return true;
    45         }
    46         if(p.fuel < C && d[p.city][p.fuel + 1] > d[p.city][p.fuel] + cc[p.city]) 
    47         {
    48             d[p.city][p.fuel + 1] = d[p.city][p.fuel] + cc[p.city];
    49             P nxt = p;
    50             nxt.fuel++;
    51             nxt.cost += cc[p.city];
    52             q.push(nxt);
    53         }
    54 
    55         int u = p.city;
    56         for(int i = 0; i < (int) g[u].size(); i++)
    57         {
    58             const edge &e = g[u][i];
    59             if(e.dis <= p.fuel && d[e.to][p.fuel - e.dis] > p.cost)
    60             {
    61                 d[e.to][p.fuel - e.dis] = p.cost;
    62                 P nxt = p;
    63                 nxt.fuel -= e.dis;
    64                 nxt.city = e.to;
    65                 q.push(nxt);
    66             }
    67         }
    68     }
    69     return false;
    70 }
    71 
    72 int main()
    73 {
    74     //freopen("11367.txt", "r", stdin);
    75     cin>>N>>M;
    76     for(int i = 0; i < N; i++)
    77         scanf("%d", &cc[i]);
    78 
    79     int u, v, c;
    80     for(int i = 1; i <= M; i++)
    81     {
    82         scanf("%d%d%d", &u, &v, &c);
    83         g[u].push_back(edge(v, c));
    84         g[v].push_back(edge(u, c));
    85     }    
    86 
    87     cin>>Q;
    88     while(Q--)
    89     {
    90         cin>>C>>S>>T;
    91         memset(d, 0x3f, sizeof(d));
    92         if(solve())    cout<<ans.cost<<endl;
    93         else puts("impossible");
    94     }
    95     return 0;
    96 }

     

  • 相关阅读:
    TCP发送窗口更新tcp_ack_update_window
    关于nginx
    通过导出表找导出函数
    导出表
    静态链接库、动态链接库
    数据目录
    扩大节、合并节
    新增一个节
    用程序在代码节空白处加代码
    节空白处添加代码
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/8948048.html
Copyright © 2020-2023  润新知