POJ 3311 Hie with the Pie(经典TSP问题)

6 篇文章 3 订阅



题意:一个人从0送外卖,每次送外卖不超过10个地方,给你两两之间所需时间,求送完外卖回到店里的总时间最小,每个地方可以经历到任意次。

思路:弗洛伊德处理下就好了,然后就是经典tsp了

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 12;
const int INF = 0x3f3f3f3f;
int dp[maxn][1<<maxn], dis[maxn][maxn], n;
int main()
{
    while(~scanf("%d", &n), n)
    {
        int x;
        for(int i = 0; i <= n; i++)
            for(int j = 0; j <= n; j++)
            {
                scanf("%d", &x);
                dis[i][j] = x;
            }
        for(int k = 0; k <= n; k++) //任意次数就直接弗洛伊德
            for(int i = 0; i <= n; i++)
                for(int j = 0; j <= n; j++)
                    dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);
        memset(dp, INF, sizeof(dp));
        dp[0][0] = 0; //能回到原点 0不要标记掉
        int tot = (1<<(n+1))-1;
        for(int state = 0; state <= tot; state++)
        {
            for(int i = 0; i <= n; i++) //先枚举中间点
            {
                if(dp[i][state] != INF) //如果这个状态算过才能算下面的最优
                {  //就算最短路经过了其他没标记过的点, 最后每个状态都会经历到,肯定会被更新成最优
                    for(int k = 0; k <= n; k++)
                    {
                        if(state&(1<<k)) continue;
                        dp[k][state|(1<<k)] = min(dp[k][state|(1<<k)], dp[i][state]+dis[i][k]);
                    }
                }
            }
        }
//        int ans = INF;
//        for(int i = 1; i <= n; i++)
//            ans = min(ans, dp[i][tot-1]+dis[i][0]);
        printf("%d\n", dp[0][tot]);
    }
    return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值