uva 11367 dijkstra+dp状态压缩

来源:互联网 发布:京都特色民宿酒店知乎 编辑:程序博客网 时间:2024/04/30 03:15

题意:给出n个地点 和 每个地点的油价 ,有 m 条边 , 并给出每条边长度 。1单位汽油可以走1千米  , 油箱的容量为 c , 在初始点 s 时 , 油箱中的油为 0 , 求s 到 t 的最小花费 。


解法: 定义 状态 d[i][j] 表示到达 地点 i 且油箱中有 j 单位油时的最小 花费。 对于状态的转移时 , 有两种方法:

1、把每个点的所有状态都求出

2、不把每个点的状态都求出 , 而是一单位一单位的加油。


对于第一种方法 , 会超时 , 因为每个点的状态太多 , 但是能用的状态就那么几个 , 因此得用第二种方法 , 进行状态的转移。

确定状态转移之后 , 我就可以用 dijkstra + 堆进行优化。


代码:

#include <iostream>#include <string.h>#include <stdio.h>#include <queue>#include <vector>using namespace std;#define maxn 1010#define INF 0xfffffffstruct node{    int u , fle , d;    bool operator < (const node& chs)  const    {        return d > chs.d;    }};struct edge{    int u , d;    int next;}grap[20010];int n , m;int ci[maxn] , pre[maxn][110];int head[maxn];int d[maxn][110];int s , t , c;void init(){    memset(head , -1 , sizeof(head));}void add_edge(int x , int y , int z , int &k){    grap[k].u = y;    grap[k].d = z;    grap[k].next = head[x];    head[x] = k++;    grap[k].u = x;    grap[k].d = z;    grap[k].next = head[y];    head[y] = k++;}int dijkstra(){    priority_queue<node>q;    memset(pre , 0 , sizeof(pre));    int i ;    memset(d , -1 , sizeof(d));    d[s][0] = 0;    node f , e;    e.u = s;    e.fle = e.d = 0;    q.push(e);    while(!q.empty())    {        e = q.top();  q.pop();        if(e.u == t)  return e.d;        for(i = head[e.u]; i != -1 ; i = grap[i].next)        {            if(e.fle >= grap[i].d)            {                int fuel=e.fle-grap[i].d;                if(d[grap[i].u][fuel]==-1||d[grap[i].u][fuel]>e.d)                {                    f.u = grap[i].u;                    f.fle = fuel;                    f.d =  e.d;                    d[grap[i].u][fuel] = e.d;                //    printf("tt.u %d cost %d fuel %d\n",tt.u,tt.fuel,tt.cost);                    q.push(f);                }            }            if(e.fle < c)            {                if(d[e.u][e.fle+1]==-1||d[e.u][e.fle+1]>e.d+ci[e.u])                {                    f.u = e.u;                    f.fle = e.fle+1;                    f.d =  e.d+ci[e.u];                    d[e.u][f.fle] = e.d+ci[e.u];                //    printf("tt.u %d cost %d fuel %d\n",tt.u,tt.fuel,tt.cost);                    q.push(f);                }            }        }    }    return -1;}int main(){    while(scanf("%d %d" , &n , &m) != EOF)    {        init();        int i , x , y , z;        int k = 0;        for(i = 0; i < n; i++)            scanf("%d" , &ci[i]);        for(i = 0; i < m; i++)        {            scanf("%d %d %d" , &x , &y , &z);            add_edge(x , y , z , k);        }        int p;        scanf("%d" , &p);        for(i = 1; i <= p; i++)        {            scanf("%d %d %d" , &c , &s , &t);            x = dijkstra();            if(x == -1)  cout<<"impossible"<<endl;            else                printf("%d\n" , x);        }    }    return 0;}


1 0
原创粉丝点击