uva11367 - Full Tank? 最短路 DP

  F: Full Tank? 

After going through the receipts from your car trip through Europe this summer, you realised that the gas prices varied between the cities you visited. Maybe you could have saved some money if you were a bit more clever about where you filled your fuel?

To help other tourists (and save money yourself next time), you want to write a program for finding the cheapest way to travel between cities, filling your tank on the way. We assume that all cars use one unit of fuel per unit of distance, and start with an empty gas tank.

Input 

The first line of input gives 1n1000 and 0m10000 , the number of cities and roads. Then follows a line with n integers 1pi100 , where pi is the fuel price in the i th city. Then follow m lines with three integers 0u , v < n and 1d100 , telling that there is a road between u and v with length d . Then comes a line with the number 1q100 , giving the number of queries, and q lines with three integers 1c100 , s and e , where c is the fuel capacity of the vehicle, s is the starting city, and e is the goal.

Output 

For each query, output the price of the cheapest trip from s to e using a car with the given capacity, or ``impossible" if there is no way of getting from s to e with the given car.

Sample Input 

5 5 
10 10 20 12 13 
0 1 9 
0 2 8 
1 2 1 
1 3 11 
2 3 7 
2 
10 0 3 
20 1 4

Sample Output 

170 
impossible

 

 

  N个点M条无向边,给你每个点的油价。Q个询问,每次询问给你油箱容量和起点终点,一单位距离花一单位油,问起点到终点最少花多少钱,不能到达输出-1。

  类似于以前马里奥那个,思路是把(u,fuel)当成一个点,就是一个二维的,在某个位置有多少油量这样一个状态当成一个点,用dijkstra,根据条件判断当前点连接的点(加一单位油或者花费油走到另一个位置,油要一单位一单位加,节省时间)。一旦到达终点就返回。

  这种题的思路是把原来的图根据二维关系状态转移的情况构成一个新图,求最短路。优先队列的dijkstra复杂度MlogN。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
#include<queue>
#include<map>
using namespace std;

typedef pair<int,int> pii;

const int MAXN=1010;
const int MAXM=25;
const int MAXC=110;
const int MAXNODE=100010;
const int LOGMAXN=50;
const int INF=0x3f3f3f3f;

int N,M,Q,S,E,C;
int p[MAXN];

struct Point{
    int u,fuel,d;
    bool operator < (const Point& rhs) const{
        return d>rhs.d;
    }
};
struct Edge{
    int u,v,dist;
};

struct Dijkstra{
    int n;
    int d[MAXN][MAXC],vis[MAXN][MAXC];
    vector<int> G[MAXN];
    vector<Edge> edges;

    void init(int n){
        this->n=n;
        for(int i=0;i<n;i++) G[i].clear();
        edges.clear();
    }
    void add_edge(int u,int v,int dist){
        edges.push_back((Edge){u,v,dist});
        int m=edges.size()-1;
        G[u].push_back(m);
    }
    int dijkstra(int S,int E,int C){
        priority_queue<Point> q;
        memset(d,INF,sizeof(d));
        memset(vis,0,sizeof(vis));
        d[S][0]=0;
        q.push((Point){S,0,0});
        while(!q.empty()){
            Point tmp=q.top();
            q.pop();
            int u=tmp.u,fuel=tmp.fuel;
            if(u==E) return d[u][fuel];
            if(vis[u][fuel]) continue;
            vis[u][fuel]=1;
            if(fuel<C&&d[u][fuel]+p[u]<d[u][fuel+1]){
                d[u][fuel+1]=d[u][fuel]+p[u];
                q.push((Point){u,fuel+1,d[u][fuel+1]});
            }
            int len=G[u].size();
            for(int i=0;i<len;i++){
                Edge& e=edges[G[u][i]];
                if(fuel>=e.dist&&d[u][fuel]<d[e.v][fuel-e.dist]){
                    d[e.v][fuel-e.dist]=d[u][fuel];
                    q.push((Point){e.v,fuel-e.dist,d[e.v][fuel-e.dist]});
                }
            }
        }
        return -1;
    }
}solver;

int main(){
    freopen("in.txt","r",stdin);
    while(scanf("%d%d",&N,&M)!=EOF){
        for(int i=0;i<N;i++) scanf("%d",&p[i]);
        solver.init(N);
        int u,v,dist;
        for(int i=0;i<M;i++){
            scanf("%d%d%d",&u,&v,&dist);
            solver.add_edge(u,v,dist);
            solver.add_edge(v,u,dist);
        }
        scanf("%d",&Q);
        while(Q--){
            scanf("%d%d%d",&C,&S,&E);
            int ans=solver.dijkstra(S,E,C);
            if(ans==-1) printf("impossible\n");
            else printf("%d\n",ans);
        }
    }
    return 0;
}


 

你可能感兴趣的:(uva11367 - Full Tank? 最短路 DP)