hdu 4784 Dinner Coming Soon

            spfa+优先队列。刚开始只用的spfa,结果tle到死。然后听队友说要用到优先队列,想了想,对时间分层的话的确每一个结点都只进队列一次即可,因为只有大时间才能更新出小时间,然后就wa成shi了。按队友写的改了才过得,好伤心的说,这是好题。。。

            附上代码供大家对拍吧。

 

#include<algorithm>

#include<iostream>

#include<cstring>

#include<cstdio>

#include<vector>

#include<queue>

#include<cmath>

#define LL long long

#define CLR(a, b) memset(a, b, sizeof(a))

#define REP(i, n) for(int i = 0; i < n; i ++)

#define FF(i, a, b) for(int i = a; i < b; i ++)

#define FD(i, a, b) for(int i = a; i >= b; i --)

#define swp(a, b) a^=b^=a^=b;



using namespace std;



struct Node

{

    int u, b, vd, t;

    Node(){}

    Node(int a, int b, int c, int d):u(a), b(b), vd(c), t(d){}

    bool operator < (const Node &rhs) const

    {

        return t < rhs.t;

    }

};



struct Edge

{

    int u, v, t, m;

    Edge(){}

    Edge(int a, int b, int c, int d):u(a), v(b), t(c), m(d){}

}E[420];



int fir[220], next[440], tot;



void Add_Edge(int u, int v, int t, int m)

{

    E[tot] = Edge(u, v, t, m);

    next[tot] = fir[u]; fir[u] = tot ++;

}



int dp[110][6][7][220];

bool vis[110][6][7][220];

int p[110][7];

int N, M, B, K, R, T;



priority_queue<Node>q;



void relax(int u, int b, int vd, int t, int val)

{

    if ((u == 1 || u == N) && vd != 0) return ;

    if(dp[u][b][vd][t] < val)

    {

        dp[u][b][vd][t] = val;

        if(!vis[u][b][vd][t])

        {

            Node w = Node(u, b, vd, t);

            q.push(w);

            vis[u][b][vd][t] = true;

        }

    }

}



void spfa()

{

    int u, v, m, t,vd, b;

    Node a = Node(1, 0, 0, T);

    CLR(dp, -1);CLR(vis, false);

    dp[1][0][0][T] = R;

    vis[1][0][0][T] = true;

    q.push(a);

    while(!q.empty())

    {

        a = q.top();q.pop();

        u = a.u;b = a.b;vd = a.vd;t = a.t;

        if(u == N) continue;

        if(t > 0)

        {

            int val = dp[u][b][vd][t];

            relax(u, b, (vd + 1) % K, t - 1, val);

            if(p[u][vd] != -1)

            {

                if(b > 0)

                {

                    relax(u, b - 1, (vd + 1) % K, t - 1, val + p[u][vd]);

                }

                if(b < B && val >= p[u][vd])

                {

                    relax(u, b + 1, (vd + 1) % K, t - 1, val - p[u][vd]);

                }

            }

        }

        for(int i = fir[u]; ~i; i = next[i])

        {

            int tmp = t - E[i].t;

            if(tmp < 0) continue;

            v = E[i].v;

            int val = dp[u][b][vd][t] - E[i].m;

            if(val < 0) continue;

            relax(v, b, vd, tmp, val);

            if(p[u][vd] != -1)

            {

                if(b > 0)

                {

                    relax(v, b - 1, vd, tmp, val + p[u][vd]);

                }

                if(b < B && val >= p[u][vd])

                {

                    relax(v, b + 1, vd, tmp, val - p[u][vd]);

                }

            }

        }

    }

}



int main()

{

    int Time, cas = 1;

    scanf("%d", &Time);

    while(Time --)

    {

        scanf("%d%d%d%d%d%d", &N, &M, &B, &K, &R, &T);

        for(int i = 0; i < K; i ++)

        {

            for(int j = 1; j <= N; j ++)

            {

                scanf("%d", &p[j][i]);

            }

        }

        CLR(fir, -1);tot = 0;

        int u, v, t, m;

        for(int i = 0; i < M; i ++)

        {

            scanf("%d%d%d%d", &u, &v, &t, &m);

            Add_Edge(u, v, t, m);

        }

        spfa();

        int ans = -1;

        for(int i = 0; i <= B; i ++)

        {

            for(int j = 0; j <= T; j ++)

            {

                ans = max(ans, dp[N][i][0][j]);

            }

        }

        if(ans != -1) printf("Case #%d: %d\n", cas ++, ans);

        else printf("Case #%d: Forever Alone\n", cas ++);

    }

}


 

 

你可能感兴趣的:(inner)