hdu 4144 状态压缩dp

#include<map>

#include<set>

#include<cmath>

#include<queue>

#include<cstdio>

#include<vector>

#include<string>

#include<cstdlib>

#include<cstring>

#include<iostream>

#include<algorithm>

#define Maxn 52

#define Maxm 100010

#define LL __int64

#define Abs(x) ((x)>0?(x):(-x))

#define lson(x) (x<<1)

#define rson(x) (x<<1|1)

#define inf 0x3f3f3f3f

#define Mod 1000000007

using namespace std;

int dis[Maxn][Maxn],p[Maxn],t[Maxn],ft[Maxn],dp[1<<8][Maxn][1<<8],n,m,k;

LL fast[Maxn];

void init()

{

    memset(dis,63,sizeof(dis));

    memset(fast,0,sizeof(fast));

    memset(dp,63,sizeof(dp));

    memset(ft,63,sizeof(ft));

}

void floyd()

{

    int i,j,k;

    for(k=1;k<=n;k++){

        dis[k][k]=0;

        for(i=1;i<=n;i++){

            for(j=1;j<=n;j++){

                dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);

            }

        }

    }

}

int check(int p)

{

    int temp=0;

    for(int i=1;i<=k;i++) if(fast[i]&(1LL<<p)) temp|=(1<<(i-1));

    return temp;

}

void Min(int &a,int b)

{

    a=a>b?b:a;

}

int solve()

{

    int i,j,r,ki,kj,fi,fj,N;

    N=(1<<k)-1;

    dp[0][1][0]=0;

    for(ki=0;ki<=N;ki++){

        for(fi=0;fi<=N;fi++) if((ki&fi)==ki){

            for(i=1;i<=n;i++)if(dp[ki][i][fi]<inf){

                for(kj=1;kj<=k;kj++) if((ki&(1<<(kj-1)))==0){

                    int fast=check(p[kj]);

                    Min(dp[ki|(1<<(kj-1))][p[kj]][fast|fi|(1<<(kj-1))],dp[ki][i][fi]+dis[i][p[kj]]+(((fast|fi)&(1<<(kj-1)))?ft[kj]:t[kj]));

                }

                for(j=1;j<=n;j++){

                    int fast=check(j);

                    if((fast&fi)!=fast)

                        Min(dp[ki][j][fast|fi],dp[ki][i][fi]+dis[i][j]);

                }

            }

        }

    }

    int ans=inf;

    for(i=0;i<=N;i++){

        for(j=1;j<=n;j++){

            ans=min(ans,dp[N][j][i]+dis[j][1]);

        }

    }

    return ans;

}

int main()

{

    int i,j,u,v,val,x,c,Case=0;

    int T;

    scanf("%d",&T);

    while(T--){

        init();

        scanf("%d%d%d",&n,&m,&k);

        for(i=1;i<=m;i++){

            scanf("%d%d%d",&u,&v,&val);

            dis[u][v]=dis[v][u]=min(dis[u][v],val);

        }

        for(i=1;i<=k;i++){

            scanf("%d%d%d%d",&p[i],&t[i],&ft[i],&c);

            while(c--){

                scanf("%d",&x);

                fast[i]|=(1LL<<x);

            }

        }

        floyd();

        printf("Case #%d: %d\n",++Case,solve());

    }

    return 0;

}

 

你可能感兴趣的:(HDU)