POJ 3311 Hie with the Pie

POJ 3311 Hie with the Pie
题意:有n+1个地方需要送馅饼,但是只有一个送货员,然后给出每个点到其他n个点的时间,然后找最有方案,
思路:与前两个状压dp不一样,是一个TSP问题。挑战程序设计上面的例题就是一道TSP的问题,不一样的地方就是,在找路径之前,需要用floyd把所有路径都更新为最短路径。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f
typedef long long LL;
int n;
int dp[1<<12][20];
int mapp[12][12];
int main()
{
    while(scanf("%d",&n)!=EOF,n)
    {
        for(int i=0; i<=n; i++)
            for(int j=0; j<=n; j++)
                scanf("%d",&mapp[i][j]);
           
        for(int k=0; k<=n; k++)
            for(int i=0; i<=n; i++)
                for(int j=0; j<=n; j++)
                    mapp[i][j]=min(mapp[i][j],mapp[i][k]+mapp[k][j]);
      
        for(int s=0; s<=(1<<n)-1; s++) //先对1~n 的点枚举
        {
            for(int i=1; i<=n; i++)
            {
                if(s&(1<<(i-1)))   // 如果情况i在集合s中
                {
                    if(s == (1<<(i-1))) //如果当前的集合s与情况i相同,最有解是从0出发到达i,也是dp的边界情况
                        dp[s][i]=mapp[0][i];
                    else
                    {
                        dp[s][i]=inf;
                        for(int j=1; j<=n; j++)
                        {
                            if(s & (1<<(j-1)) && i!=j) //枚举不是城市I的其他城市  
                            {
                                dp[s][i]=min(dp[s][i],dp[s^(1<<(i-1))][j]+mapp[j][i]); 
                                //在没经过城市i的状态中,寻找合适的中间点j使得距离更短  
                            }
                        }
                    }
                }
            }
        }
        int ans=inf;
        // 找到从1~n的最短路之后,然后从每个点返回到0的距离
        for(int i=1; i<=n; i++)
        {
            ans=min(ans,dp[(1<<n)-1][i]+mapp[i][0]);
        }
        printf("%d\n",ans);
    }
    return 0;
}
posted @ 2016-03-28 13:59  zzuli_柚子  阅读(161)  评论(0编辑  收藏  举报