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

来源:互联网 发布:文字抓取软件 编辑:程序博客网 时间:2024/05/17 02:25



题意:一个人从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;}


原创粉丝点击