• POJ 3311 Hie with the Pie:TSP(旅行商)【节点可多次经过】


    题目链接:http://poj.org/problem?id=3311

    题意:

      你在0号点(pizza店),要往1到n号节点送pizza。

      每个节点可以重复经过。

      给你一个(n+1)*(n+1)的邻接矩阵,表示各点之间距离。

      问你送完所有pizza再返回店里的最短路程。

    题解:

      与传统TSP相比,唯一变化的条件是每个节点可以经过多次。

      所以也就是转移的时候不用再判断要去的节点j是否去过。

      先floyd预处理出两点之间最短路。然后把(!((state>>j)&1))去掉,套TSP模板就好啦。

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <stack>
     5 #define MAX_N 15
     6 #define MAX_S (1<<13)
     7 #define INF 10000000
     8 
     9 using namespace std;
    10 
    11 int n;
    12 int ans;
    13 int dp[MAX_S][MAX_N];
    14 int dis[MAX_N][MAX_N];
    15 
    16 void floyd()
    17 {
    18     for(int k=0;k<=n;k++)
    19     {
    20         for(int i=0;i<=n;i++)
    21         {
    22             for(int j=0;j<=n;j++)
    23             {
    24                 if(i!=j && j!=k && i!=k)
    25                 {
    26                     dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    27                 }
    28             }
    29         }
    30     }
    31 }
    32 
    33 void read()
    34 {
    35     for(int i=0;i<=n;i++)
    36     {
    37         for(int j=0;j<=n;j++)
    38         {
    39             cin>>dis[i][j];
    40         }
    41     }
    42 }
    43 
    44 void solve()
    45 {
    46     floyd();
    47     memset(dp,-1,sizeof(dp));
    48     dp[0][0]=0;
    49     for(int state=0;state<(1<<(n+1));state++)
    50     {
    51         for(int i=0;i<=n;i++)
    52         {
    53             if(dp[state][i]!=-1)
    54             {
    55                 for(int j=0;j<=n;j++)
    56                 {
    57                     if(dp[state|(1<<j)][j]==-1 || dp[state|(1<<j)][j]>dp[state][i]+dis[i][j])
    58                     {
    59                         dp[state|(1<<j)][j]=dp[state][i]+dis[i][j];
    60                     }
    61                 }
    62             }
    63         }
    64     }
    65     ans=INF;
    66     for(int i=0;i<=n;i++)
    67     {
    68         if(dp[(1<<(n+1))-1][i]!=-1)
    69         {
    70             ans=min(ans,dp[(1<<(n+1))-1][i]+dis[i][0]);
    71         }
    72     }
    73 }
    74 
    75 void print()
    76 {
    77     cout<<ans<<endl;
    78 }
    79 
    80 int main()
    81 {
    82     while(cin>>n)
    83     {
    84         if(n==0) break;
    85         read();
    86         solve();
    87         print();
    88     }
    89 }
  • 相关阅读:
    C#中的接口和类的不同点
    值类型和引用类型的区别?
    时隔两年再次操刀NPOI合并单元格
    二.Docker下安装和运行Mysql
    一.CentOS8下的Docker安装
    .NetCore3.1使用Autofac
    .NET Core 3.1使用Swagger
    数组排序和数组对象排序
    C# 操作Excel , 支持超链接 跳转Sheet 页面,HSSFHyperlink函数
    MVC导入Excel通过NPOI
  • 原文地址:https://www.cnblogs.com/Leohh/p/7382781.html
Copyright © 2020-2023  润新知