Hie with the Pie POJ - 3311

原题链接

考察:状压dp

本题是731. 毕业旅行问题的延伸

思路:

       与上面那道题不同的是每个点至少走一次,而不是只能走一次.普通的dp求出的是0到i点的最短距离(且每个点都经过一次),但这里我们还需要回程,也就是还需要求出i到0点的最短距离.我们手操可以发现ans=每个点都经过一次的最短距离+回程的最短距离.第一部分可以通过dp求出,第二部分可以用floyd.

复制代码
 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 using namespace std;
 6 const int N = 11,INF = 0x3f3f3f3f;
 7 int w[N][N],n,f[1<<N][N];
 8 int main()
 9 {
10     while(scanf("%d",&n)!=EOF&&n)
11     {
12         n++;
13         int ans  = INF,all = (1<<n)-1; memset(f,0x3f,sizeof f);
14         for(int i=0;i<n;i++)
15           for(int j=0;j<n;j++) scanf("%d",&w[i][j]);
16         for(int i=0;i<n;i++)
17           for(int j=0;j<n;j++)
18             for(int k=0;k<n;k++)
19               w[i][j] = min(w[i][k]+w[k][j],w[i][j]);
20         f[1][0] = 0;
21         for(int i=0;i<1<<n;i++)
22           for(int j=0;j<n;j++)
23            if(i>>j&1)
24            {
25                 for(int k=0;k<n;k++)
26                if(i-(1<<j)>>k&1)
27                  f[i][j] = min(f[i-(1<<j)][k]+w[k][j],f[i][j]);
28              if(i==all)
29                ans = min(ans,f[i][j]+w[j][0]);
30            }     
31         printf("%d\n",ans);
32     }
33     return 0;
34 }
复制代码

 

posted @   acmloser  阅读(45)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示