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;
}

 

posted @ 2013-08-29 17:05  fangguo  阅读(273)  评论(0编辑  收藏  举报