POJ 3635 Full Tank?(BFS)

来源:互联网 发布:大智慧软件使用 编辑:程序博客网 时间:2024/05/05 10:06

题目链接: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;}


原创粉丝点击