poj3311 Hie with the Pie(最短路+状态dp)

如果我是新手我肯定用最短路做,结果肯定被坑,因为送外卖的人可以重复的走某个道路多次,反正只要能够使最后的路程最短并且会回到送外外卖的起点就ok。那么只能用状态压缩dp了,看了下数据范围很小,状压无压力。

设置状态:

dp[st][k] 状态为st是终点为k的最短距离。
状态方程:dp[st][k] = min(dp[st][k], dp[i][j] + dis[j][k])

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define oo 0x3f3f3f3f
int dp[(1<<11)+1][11];
int Map[11][11];
int n;

void Floyd()
{
    for(int i=0;i<=n;i++)
        for(int j=0;j<=n;j++)
            for(int k=0;k<=n;k++)
            Map[i][j]=min(Map[i][j],Map[i][k]+Map[k][j]);
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                scanf("%d",&Map[i][j]);
        Floyd();
        memset(dp,0x3f,sizeof dp);
        int all=(1<<(n+1))-1;
        dp[1][0]=0;
        for(int i=0;i<=all;i++)
        {
            for(int j=0;j<=n;j++)
            {
                if(!(i&(1<<j))) continue;
                if(dp[i][j]>=oo) continue;
                for(int k=0;k<=n;k++)
                {
                    if(k==j) continue;
                    int st=i|(1<<k);
                    dp[st][k]=min(dp[st][k],dp[i][j]+Map[j][k]);
                }
            }
        }
        printf("%d\n",dp[all][0]);
    }
    return 0;
}





















你可能感兴趣的:(dp,poj)