zoukankan      html  css  js  c++  java
  • 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 }

     

  • 相关阅读:
    java io系列23之 BufferedReader(字符缓冲输入流)
    java io系列22之 FileReader和FileWriter
    java io系列21之 InputStreamReader和OutputStreamWriter
    java io系列20之 PipedReader和PipedWriter
    java io系列19之 CharArrayWriter(字符数组输出流)
    java io系列18之 CharArrayReader(字符数组输入流)
    java io系列17之 System.out.println("hello world")原理
    java io系列16之 PrintStream(打印输出流)详解
    java io系列15之 DataOutputStream(数据输出流)的认知、源码和示例
    java io系列14之 DataInputStream(数据输入流)的认知、源码和示例
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/8948048.html
Copyright © 2011-2022 走看看