HDOJ 3001 状态压缩

题意   经过任意一条边最多两次   遍历所有节点

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#define inf 0x1f1f1f1f
using namespace std;

int N,M,map[11][11],arr[32];
int hash[12] = {0,1,3,9,27,81,243,729,2187,6561,19683,59049};
int dp[177777][11];

void work( int num )
{
    int k = 1;
    memset( arr,0,sizeof(arr) );
    while( num )
    {
        arr[k++] = num%3;
        num /= 3;
    }
}
int main( )
{
    int i,j,k,t,u,v,val,res;
    while( scanf("%d%d",&N,&M) != EOF )
    {
        memset( map,inf,sizeof(map) );
        for( i = 1; i <= M; i++ )
        {
            scanf("%d%d%d",&u,&v,&val);
            if( val < map[u][v] )map[u][v] = map[v][u] = val;
        }
        memset( dp,inf,sizeof(dp) );
        for( i = 1; i <= N; i++ )
            dp[hash[i]][i] = 0;
        res = inf;
        for( i = 1; i < hash[N+1]; i++ )
        {
            int vis_all = 1;work(i);
            for( j = 1; j <= N; j++ )
            {
                if( arr[j] == 0 )vis_all = 0;
                if( dp[i][j] == inf ) continue;
                for( k = 1; k <= N; k++ )
                {
                    if( j == k )          continue;
                    if( map[j][k] == inf )continue;
                    if( arr[k] >= 2 )     continue;
                    int stu = i + hash[k];
                    dp[stu][k] = min( dp[stu][k],dp[i][j] + map[j][k] );
                }
            }
            if( vis_all )
            for( j = 1; j <= N; j++ )
            res = min( res, dp[i][j] );
        }
        if( res != inf )
             printf("%d\n",res);
        else printf("-1\n");
    }
    return 0;
}

  

posted on 2013-05-04 10:18  浪舟  阅读(156)  评论(0编辑  收藏  举报

导航