lightoj 1254 - Prison Break

题目链接:http://lightoj.com/volume_showproblem.php?problem=1254

分析题意:说的是个凡人的逃跑,有辆汽车,其邮箱容量是cap<=100。然后有n个城市,m条城市之间的距离,汽车的耗油量是1:1的。开始油箱里面是没有油的,有Q个询问,从u到v油箱的容量为cap的时候的最小花费,不能到达就输出impossible,否则输出最小花费。

这个就是多状态的最短路,据基础题。

设定状态dis[u][r]表示到达u点汽车剩余油量为r时的最小费用。在就是对于每个城市要存的数据的,剩余油量,及对应的花费,然后就是点的标号。(i,j,k),优先队列中以费用小的优先。

typedef, int> iii;

/*****************************************
Author      :Crazy_AC(JamesQi)
Time        :2015
File Name   :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef pair ii;
typedef pair iii;
const double eps = 1e-10;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn =1e3 + 10;
vector G[maxn];
int n,m;
int cap;
int dis[maxn][110];
int cost[maxn];
int solve(int st,int ed){
    priority_queue, greater > que;
    memset(dis, 0x7f, sizeof dis);
    dis[st][0] = 0;
    int ret = 0;
    que.push(iii(ii(dis[st][0], 0), st));
    while(!que.empty()){
        iii now = que.top();
        que.pop();
        int u = now.second;
        int w = now.first.first;
        int r = now.first.second;
        if (w > dis[u][r]) continue;
        if (u == ed) return dis[u][r];
        int size = G[u].size();
        for (int i = 0;i < size;++i){
            int v = G[u][i].first;
            int len = G[u][i].second;
            if (len > cap) continue;
            if (r >= len && dis[v][r - len] > dis[u][r]){
                dis[v][r - len] = dis[u][r];
                que.push(iii(ii(dis[v][r - len], r - len), v));
            }
        }
        if (r < cap){
            dis[u][r + 1] = dis[u][r] + cost[u];
            que.push(iii(ii(dis[u][r + 1], r + 1), u));
        }
    }
    return INF;
}
int main()
{    
    // freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    int t, icase = 0;
    cin >> t;
    while(t--){
        cin >> n >> m;
        for (int i = 0;i < n;++i)
            cin >> cost[i];
        int u, v, w;
        for (int i = 0;i < n;++i)
            G[i].clear();
        for (int i = 0;i < m;++i){
            cin >> u >> v >> w;
            G[u].push_back(ii(v, w));
            G[v].push_back(ii(u, w));
        }
        printf("Case %d:\n", ++icase);
        int Q;
        cin >> Q;
        // cout << "Q = " << Q << endl;
        while(Q--){
            cin >> cap >> u >> v;
            int ans = solve(u, v);
            if (ans == INF) puts("impossible");
            else cout << ans << endl;
        }
    }
    return 0;
}


你可能感兴趣的:(图论-最短路)