HDU 4114 Disney's FastPass

传送门

#include <bits/stdc++.h>
using namespace std;
#define prt(k) cerr<<#k" = "<<k<<" "
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 55;
int g[N][N];
int n, m, K;
int p[N], T[N], FT[N];
int d[N][333][332];
int card[N];

void init()
{
    memset(card, 0, sizeof card);
}
int bfs()
{
    int ans = INF;
    d[1][0][0] = 0;
    for (int s1=0;s1<(1<<K);s1++) for (int s2=0;s2<(1<<K);s2++) {
        for (int i=1;i<=n;i++) {
            int now = d[i][s1][s2];
            if (now == INF) continue;
            if (s2 == (1<<K)-1) ans=min(ans, now + g[i][1]);
            for (int j=0;j<K;j++) if (!(s2>>j & 1)) {
                int &nxt = d[p[j] ][s1][s2|(1<<j)];
                int add = g[i][p[j]];
                if (s1>>j & 1) add += FT[j];
                else add += T[j];
                nxt=min(nxt, now + add);
            }
            for (int j=1;j<=n;j++) {
                int &nxt = d[j][s1|card[j]][s2];
                nxt = min(nxt, now + g[i][j]);
            }
        }
    }
    return ans;
}
int main()
{
    int re; cin>>re; int ca = 1;
    while (re--) {
        cin >> n >> m >> K;
        init();
        memset(g, 63, sizeof g);
        for (int i=0;i<=n;i++) g[i][i] = 0;
        for (int i=0;i<m;i++) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            g[u][v] = g[v][u] = w;
        }
        for (int k=1;k<=n;k++)
        for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
        memset(d, 63, sizeof d);
        for (int i=0;i<K;i++) {
            scanf("%d", &p[i]);
            scanf("%d%d", T+i, FT+i);
            int sz; scanf("%d", &sz);
            while (sz--) {
                int x; scanf("%d", &x);
                card[x] |= 1<<i;
            }
        }
        printf("Case #%d: %d\n", ca++, bfs());
    }
    return 0;
}

你可能感兴趣的:(HDU 4114 Disney's FastPass)