IPUOJ24101旅行商问题(状压dp)
旅行商问题·基础版
题目↓(建议全屏看图)
挺简单的 集合状压,具体看代码吧
- #include<bits/stdc++.h>
- using namespace std;
- #define fr(g,h) for(int g = 0; g < h; g++)
- const int N = 25, M = 2100000;
- int n,nn,mm,a[N][N],f[N][M];
- inline void init ()
- {
- scanf("%d",&n);
- fr(i,n)
- fr(j,n)
- cin >> a[i][j];
- memset(f, 0x3f, sizeof f);
- }
- void floyd()
- {
- fr(k,n)
- fr(i,n)
- fr(j,n)
- a[i][j] = min(a[i][j], a[i][k] + a[k][j]);
- }
- void dp()
- {
- for(int s = 1; s <= (1 << n) - 1; s++) //从第一个开始走过 (这个地方s的优化还是蛮重要的,暴力开210万只能险过)
- fr(i,n)
- fr(j,n)
- if(s & (1 << j))
- f[i][s|(1<<i)] = min(f[i][s|(1<<i)], f[j][s] + a[i][j]);
- }
- int main()
- {
- init();
- f[0][1] = 0;
- floyd();
- dp();
- cout << f[0][(1<<n) - 1];
- return 0;
- }
旅行商问题·进阶版
- //旅行商2
- #include <bits/stdc++.h>
- using namespace std;
- #define fr(g,h) for(int g = 0; g < h; g++)
- const int N = 13, M = 531441 * 3; //M是3的13次方
- int pow3[N + 1], n;
- int a[N][N], f[N][M];
- inline void init ()
- {
- scanf("%d",&n);
- fr(i,n)
- fr(j,n)
- cin >> a[i][j];
- memset(f, 0x3f, sizeof f);
- }
- void floyd()
- {
- fr(k,n)
- fr(i,n)
- fr(j,n)
- a[i][j] = min(a[i][j], a[i][k] + a[k][j]);
- }
- int main()
- {
- pow3[0] = 1;
- for (int i = 1; i <= N; ++i) pow3[i] = pow3[i - 1] * 3; //预处理3的指数表
- init();
- floyd();
- int nn = pow3[n] - 1;
- f[0][1] = 0;
- for (int k = 1; k <= nn; k++)
- for (int i = 0; i < n; i++) {
- if (f[i][k] == 0x3f3f3f3f) continue;
- for (int j = 0; j < n; j++) {
- if (i == j) continue;
- int x = pow3[j];
- if ((k / x) % 3 < 2) {
- int kn = k + x;
- f[j][kn] = min(f[j][kn], f[i][k] + a[i][j]);
- }
- }
- }
- printf("%d", f[0][nn]);
- return 0;
- }
满堂花醉三千客,一剑霜寒十四州
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步