现在的位置: 首页 > 综合 > 正文

POJ 3635 Full Tank?(BFS)

2018年04月04日 ⁄ 综合 ⁄ 共 1657字 ⁄ 字号 评论关闭

题目链接:Click here~~

题意:

n 个点的无向图,边权值为距离,点权值为油价。你开着一辆油箱容量为 c 的坦克,从 s 到 e。问最少花费多少钱。

解题思路:

很容易想到状态, dp[i][j] 表示 到达 i 点剩余油量为 j 的时候的最小花费。

转移的时候,只有两种情况:加油 or 出发去下一节点。

加油时候只需要考虑加1升即可。因为如果加两升可以达到最优状态,那么加1升的状态再加1升同样可以扩展到最优状态。

出发去下一节点的时候,费用不变,剩余油量减少,油量不够不能到达。

但是不好找到最优状态,所以要用节点存储状态,然后用优先队列,每次弹出的节点(cost 最小)一定是最优状态。

写出来很像 bfs 啊。那就叫他 bfs 吧。

#include <queue>
#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

const int N = 1e3 + 3;

template<int N,int M>
struct Graph
{
    int top;
    struct Vertex{
        int head;
    }V[N];
    struct Edge{
        int v,w,next;
    }E[M];
    void init(){
        memset(V,-1,sizeof(V));
        top = 0;
    }
    void add_edge(int u,int v,int w){
        E[top].v = v;
        E[top].w = w;
        E[top].next = V[u].head;
        V[u].head = top++;
    }
};

Graph<1003,10003*2> g;

int price[N];

bool vis[N][103];

struct Node
{
    int u,vol,cost;
    Node(int u,int vol,int co):u(u),vol(vol),cost(co){}
    bool operator < (const Node& S) const{
        return cost > S.cost;
    }
    bool vis(){
        return ::vis[u][vol];
    }
    Node plusOil(){
        return Node(u,vol+1,cost+price[u]);
    }
};

int bfs(int s,int e,int cp)
{
    priority_queue<Node> Q;
    Q.push(Node(s,0,0));
    while(!Q.empty())
    {
        Node Cur = Q.top();
        Q.pop();
        int u = Cur.u;
        if(Cur.vis())
            continue;
        else
            vis[u][Cur.vol] = true;
        if(u == e)
            return Cur.cost;
        if(Cur.vol + 1 <= cp)
        {
            Node Next = Cur.plusOil();
            if(!Next.vis())
                Q.push(Next);
        }
        for(int i=g.V[u].head;~i;i=g.E[i].next)
        {
            int v = g.E[i].v;
            int d = g.E[i].w;
            if(Cur.vol >= d)
            {
                Node Next(v,Cur.vol-d,Cur.cost);
                if(!Next.vis())
                    Q.push(Next);
            }
        }
    }
    return -1;
}

int main()
{
    int n,m,Q;
    while(~scanf("%d%d",&n,&m))
    {
        g.init();
        for(int i=0;i<n;i++)
            scanf("%d",&price[i]);
        for(int i=0;i<m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            g.add_edge(u,v,w);
            g.add_edge(v,u,w);
        }
        scanf("%d",&Q);
        while(Q--)
        {
            memset(vis,false,sizeof(vis));
            int cp,s,e;
            scanf("%d%d%d",&cp,&s,&e);
            int ans = bfs(s,e,cp);
            if(ans == -1)
                puts("impossible");
            else
                printf("%d\n",ans);
        }
    }
    return 0;
}

抱歉!评论已关闭.