HDU 4784 Dinner Coming Soon

BFS + 优先队列。。。

按时间从小到大的优先队列。。。

注意交易不用时间,所以每走一步就要判断下一点能否交易,不管是去另外一个点还是去另一个平行宇宙。。。

Dinner Coming Soon

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 1282    Accepted Submission(s): 223


Problem Description
  Coach Pang loves his boyfriend Uncle Yang very much. Today is Uncle Yang’s birthday, Coach Pang wants to have a romantic candlelit dinner at Uncle Yang’s house and he has to arrive there in T minutes.
  There are N houses in their city numbered from 1 to N. Coach Pang lives in house 1 while Uncle Yang lives in house N. The houses are connected byM directed roads. It takes some time and usually a fee to pass one road. Coach Pang wants to reach Uncle Yang’s house before the dinner starts with as much money as possible.
  But the matter is not so simple. Coach Pang decides to do some salt trade on the way to Uncle Yang’s house. The host of each house offers a price of a bag of salt, so Coach Pang can make a profit from the price differences. Each time when Coach Pang arrives at a house (except the house 1 and the house N). He can buy one bag of salt, sell one bag of salt or do nothing. Coach Pang can carry at most B bags of salt with him, and he carries no salt when he leaves his house. The trading is so efficient that the time cost of trading can be ignored.
  However, the problem is more complicated than imagine. Coach Pang has a handheld device that can perform a journey around K parallel universes numbered from 0 to K-1. Coach Pang lives in the universe 0. When Coach Pang uses the device in universe i, he will be transported to the same place and the same time of universe (i+1) modK. The host of the house at the same place in different universe may offer a different price of salt. Luckily, the time cost and fee of the city roads are uniform among the K universes. The journey between universes costs no time but Coach Pang has to stand still watching the ads on the device for one minute every time before the device works. Remember, Coach Pang should never visit house 1 or house N in a universe other than universe 0, because the situation might become uncontrollable if he bumps into himself or his boyfriend in another universe.
  The time is running out. Coach Pang asks you to tell him whether he can arrive at Uncle Yang’s house in time, and how much money Coach Pang can have at most when the dinner starts. Coach Pang has R yuan at the start, and will end his journey immediately once he arrives at Uncle Yang’s house. He must arrive at Uncle Yang’s house in T minutes, and he can’t have negative amount of money anywhere anytime. Please help him!
 

Input
  The first line of the input is an integer C representing the number of test cases.
  For each test case, the first line will contain 6 integers N, M, B, K, R, T, as described above.
  (2 <= N <= 100, 0 <= M <= 200, 1 <= B <= 4, 2 <= K <= 5, 0 <= R <= 10 5, 0 <= T <= 200)
  The following K lines contain N integers each, indicating the price p ij (0 <= i < K, 1 <= j <= N) for a bag of salt offered by the host of house j in the universe i. The price of house 1 and house N will be marked as -1.(1 <= p ij <= 100)
  Then M lines follow, each contains 4 integers a, b, t and m, indicating that there is a road from house a to house b that costs t minutes of time and m yuan of money. (1 <= a,b <= N, a<> b, 1 <= t <=15, 0 <= m <= 100)
 

Output
  For each test case, output one line containing “Case #x: y”, where x is the case number (starting from 1) and y is the most money Coach Pang can have if he can have dinner with Uncle Yang on time.
  Print "Forever Alone" otherwise.
 

Sample Input
   
   
   
   
2 3 2 1 2 10 6 -1 1 -1 -1 5 -1 1 2 1 0 2 3 1 1 2 2 1 2 5 5 -1 -1 -1 -1 1 2 10 2 1 2 2 10
 

Sample Output
   
   
   
   
Case #1: 17 Case #2: Forever Alone
 

Source
2013 Asia Chengdu Regional Contest
 


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#define prt(k) cout<<#k" = "<<k<<endl;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
int n,m,B,K,R,T;
int p[222][222];
struct Node
{
    int u, id, t, s;
    bool operator < (Node b) const
    {
        return t > b.t;
    }
};
struct Edge
{
    int to,next,t,m;
};
int tot;
Edge edge[3333];
int head[3333];
void addedge(int u, int v, int w, int c)
{
    edge[++tot].t = w;
    edge[tot].m = c;
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot;
}
#include<queue>
int dp[111][8][222][8];
bool inq[111][8][222][8];
priority_queue<Node> q;
void bfs()
{
    while(!q.empty()) q.pop();
    q.push((Node){1,0,0,0});
    memset(inq, 0, sizeof inq);
    inq[1][0][0][0] = true;
    memset(dp, -1, sizeof dp);
    dp[1][0][0][0] = R;
    while(!q.empty())
    {
        Node u = q.top(); q.pop();
        Node tmp = u;
        if(u.u==n) continue;
        if(u.t > T) break;
        int now=u.u, id=u.id, t=u.t, s=u.s;
        if(now==1||now==n) if(id) continue;
        int old = dp[now][id][t][s];
        for(int i=head[u.u];~i;i=edge[i].next)
        {
            int m = old - edge[i].m;
            Node tmp = u;
            tmp.u = edge[i].to;
            tmp.t = u.t + edge[i].t;
            if(m < 0) continue;
            if((tmp.u==1||tmp.u==n)&& u.id>0) continue;
            if(m < 0 || t > T) continue;
            if(dp[tmp.u][tmp.id][tmp.t][tmp.s] < m)
            {
                dp[tmp.u][tmp.id][tmp.t][tmp.s] = m;
                if( !inq[tmp.u][tmp.id][tmp.t][tmp.s] )
                {
                    inq[tmp.u][tmp.id][tmp.t][tmp.s] = 1;
                    q.push(tmp);
                }
            }
            if(tmp.u!=1&&tmp.u!=n)
            {
                if(s>0)
                {
                    int m = old - edge[i].m + p[tmp.u][tmp.id];
                    Node tt = tmp;
                    tt.s --;
                    if(m > dp[tt.u][tt.id][tt.t][tt.s]  )
                    {
                        dp[tt.u][tt.id][tt.t][tt.s] = m;
                        if( !inq[tt.u][tt.id][tt.t][tt.s] )
                        {
                            inq[tt.u][tt.id][tt.t][tt.s] = 1;
                            q.push(tt);
                        }
                    }
                }
                if(s<B )
                {
                    int m = old - edge[i].m - p[tmp.u][tmp.id];
                    Node tt = tmp;
                    tt.s ++;
                    if(m > dp[tt.u][tt.id][tt.t][tt.s]  )
                    {
                        dp[tt.u][tt.id][tt.t][tt.s] = m;
                        if( !inq[tt.u][tt.id][tt.t][tt.s] )
                        {
                            inq[tt.u][tt.id][tt.t][tt.s] = 1;
                            q.push(tt);
                        }
                    }
                }
            }
        }
        if(u.u!=1 && u.u!=n)
        {
            int v = u.u;
            int id = (u.id+1)%K;
            int t = u.t + 1;
            int s = u.s;
            int m = old;
            Node tmp = u;
            tmp.id = (u.id+1)%K;
            tmp.t++;

            if(t > T) continue;
            if(dp[v][id][t][s] < m)
            {
                dp[v][id][t][s] = m;
                if(!inq[v][id][t][s] )
                {
                    inq[v][id][t][s] = 1;
                    q.push((Node){v,id,t,s});
                }
            }
            if(tmp.s > 0)
            {
                int m = old + p[tmp.u][tmp.id];
                Node tt = tmp;
                tt.s --;
                if(m > dp[tt.u][tt.id][tt.t][tt.s]  )
                {
                    dp[tt.u][tt.id][tt.t][tt.s] = m;
                    if( !inq[tt.u][tt.id][tt.t][tt.s] )
                    {
                        inq[tt.u][tt.id][tt.t][tt.s] = 1;
                        q.push(tt);
                    }
                }
            }
            if( tmp.s < B )
            {
                int m = old - p[tmp.u][tmp.id];
                Node tt = tmp;
                tt.s ++;
                if(m > dp[tt.u][tt.id][tt.t][tt.s]  )
                {
                    dp[tt.u][tt.id][tt.t][tt.s] = m;
                    if( !inq[tt.u][tt.id][tt.t][tt.s] )
                    {
                        inq[tt.u][tt.id][tt.t][tt.s] = 1;
                        q.push(tt);
                    }
                }
            }
        }
    }
    int ans = -1;
    for(int t=0;t<=T;t++) for(int i=0;i<=B;i++) ans = max(ans, dp[n][0][t][i]);
    if(ans == -1) puts("Forever Alone");
    else printf("%d\n",ans);
}
int main()
{
    int re; cin>>re; int ca=1;
    while(re--)
    {
        cin>>n>>m>>B>>K>>R>>T;
        for(int j=0;j<K;j++)
        {
            for(int i=1;i<=n;i++)
                scanf("%d", &p[i][j]);
        }
        tot = 0;
        memset(head, -1, sizeof head);
        for(int i=0;i<m;i++)
        {
            int u,v,w,c;
            scanf("%d%d%d%d",&u,&v,&w,&c);
            addedge(u,v,w,c);
        }
        printf("Case #%d: ", ca++);
        bfs();
    }
}


你可能感兴趣的:(HDU 4784 Dinner Coming Soon)