HDU4784 DP+BFS

来源:互联网 发布:软件验收测试方法 编辑:程序博客网 时间:2024/05/22 12:33

     思路还是挺简单的,不过acmicpc.info贴出来的题解太长了就自己写了一遍。。。建图的时候对于不在第0宇宙的1和N点对应的边全都不建,BFS的时候使用优先队列,以时间为优先级,然后到每一个点之后有三个决策,买盐之后去下一个点,卖盐之后去下一个点,或者直接去下一个点,分别转移一下就行了。

#include<cstdio>#include<cstring>#include<queue>using namespace std;int dp[5][505][205],vis[5][505][205];int head[2000],w[2000];int cnt,N,B,R,T;struct node{    int v,next,ct,cw;}edge[4000];struct pt{    int id,t,c;    pt(int x1,int x2,int x3)    {        c=x1,id=x2,t=x3;    }    bool operator < (const pt &a) const    {        return t>a.t;    }};void addedge(int a,int b,int t,int w){    edge[cnt].v = b;    edge[cnt].ct = t;    edge[cnt].cw = w;    edge[cnt].next = head[a];    head[a] = cnt++;}int bfs(){    memset(dp,-1,sizeof(dp));    memset(vis,0,sizeof(vis));    dp[0][1][0] = R;    priority_queue<pt>pq;    pq.push(pt(0,1,0));    vis[0][1][0] =1;    pt top = pt(0,0,0);    while(!pq.empty())    {        top = pq.top();        pq.pop();        int cc = top.c,tt = top.t,ps = top.id;        int op[3],num = 0;        op[num++] = 0;        if(cc<B&&dp[cc][ps][tt]>w[ps]&&w[ps]!=-1)op[num++] = 1;        if(cc>0&&w[ps]!=-1)op[num++] = -1;        for(int i = head[ps];i!=-1;i = edge[i].next)        {            int v = edge[i].v;            int ct = edge[i].ct;            int cw = edge[i].cw;            if(v%N == 0&&v!=N)continue;            if(v%N == 1&&v!=1)continue;            for(int j = 0;j<num;j++)            {                dp[cc+op[j]][v][tt+ct] = max(dp[cc+op[j]][v][tt+ct],dp[cc][ps][tt]-op[j]*w[ps]-cw);                if(!vis[cc+op[j]][v][tt+ct]&&dp[cc+op[j]][v][tt+ct]>=0&&tt+ct<=T&&v!=N)                {                    pq.push(pt(cc+op[j],v,tt+ct));                    vis[cc+op[j]][v][tt+ct] = 1;                }            }        }    }    int ans = -1;    for(int i = 0;i<=B;i++)        for(int j = 0;j<=T;j++)            ans = max(ans,dp[i][N][j]);    return ans;}int main(){    int M,K,t,i,j,cas = 1;    scanf("%d",&t);    while(t--)    {        cnt = 0;        memset(head,-1,sizeof(head));        scanf("%d%d%d%d%d%d",&N,&M,&B,&K,&R,&T);        for(i = 1;i<=K;i++)            for(j = 1;j<=N;j++)            {                scanf("%d",&w[(i-1)*N+j]);                if(j == 1||j == N)continue;                addedge((i-1)*N+j,i%K*N+j,1,0);            }        for(i = 1;i<=M;i++)        {            int a,b,c,d;            scanf("%d%d%d%d",&a,&b,&c,&d);            for(j = 0;j<K;j++)addedge(a+j*N,b+j*N,c,d);        }        int ans = bfs();        printf("Case #%d: ",cas++);        if(ans == -1)printf("Forever Alone\n");        else printf("%d\n",ans);    }    return 0;}


原创粉丝点击