poj3311 状压dp+floyd

先floyd预处理一遍dis,枚举所有状态,dp[ i ] [ j ]表示 以  j  为终点的状态 i 使用最小的时间

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cassert>
#include<iomanip>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const double g=10.0,eps=1e-7;
const int N=10+10,maxn=(1<<11)+10,inf=0x3f3f3f;

int dis[N][N];
int dp[maxn][N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    while(cin>>n,n)
    {
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                cin>>dis[i][j];
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
               for(int k=0;k<=n;k++)
                  dis[i][k]=min(dis[i][k],dis[i][j]+dis[j][k]);
        memset(dp,-1,sizeof dp);
        dp[1][0]=0;
        for(int i=1;i<(1<<(n+1));i++)
        {
            i|=1;
            for(int j=0;j<=n;j++)
            {
                if(dp[i][j]!=-1)
                {
                    for(int k=0;k<=n;k++)
                    {
                        if(j==k)continue;
                        if(dp[(1<<k)|i][k]==-1||dp[(1<<k)|i][k]>dp[i][j]+dis[j][k])
                            dp[(1<<k)|i][k]=dp[i][j]+dis[j][k];
                    }
                }
            }
        }
        cout<<dp[(1<<(n+1))-1][0]<<endl;
    }
    return 0;
}
/********************
0no 1yes
dp[i][k]=min(dp[i][k],a[i][j]+a[j][k])
O(n*n*n*(1<<n))
********************/
View Code

 

posted @ 2017-08-15 12:41  walfy  阅读(253)  评论(0编辑  收藏  举报