旅行商问题

总时间限制: 1000ms 内存限制: 65536kB

描述

某国家有n(1<=n<=10)座城市,给定任意两座城市间距离(不超过1000的非负整数)。一个旅行商人希望访问每座城市恰好一次(出发地任选,且最终无需返回出发地)。求最短的路径长度。

输入

第一行输入一个整数n

接下来n行,每行n个数,用空格隔开,以邻接矩阵形式给出城市间距离。该邻接矩阵是对称的,且对角线上全为0

输出

一行,最短路径的长度

样例输入
6
0 16 1 10 12 15
16 0 10 2 10 8
1 10 0 10 5 10
10 2 10 0 9 3
12 10 5 9 0 8
15 8 10 3 8 0
样例输出
19

解题思路

这个问题可以抽象为在\(n\)阶无向完全图\(K_n\)中,给定每个边加权(长度),然后在该带权图中求一条权和最小的哈密顿通路(只求解最小权和即可)。我的想法是使用深度优先搜索求解,过程中使用了set来储存通路的长度,由于set使用二叉搜索树,可以在\(O(\log n)\)时间内完成元素插入,同时自动对元素排序,并且能够在\(O(1)\)时间内获得集合的最大和最小值,以略微节省运算时间。另外使用stack容器来临时储存全局变量sum(长度和)的值。

代码
#include <bits/stdc++.h>
using namespace std;
int cities[12][12] = {};
bool visited[12] = {};
//标记去过的城市,如果去过了,则记true
int n;
int sum;
set<int> path;
stack<int> temp;
void dfs(int start)
{
bool flag = true;
for (int i = 1; i <= n; i++)
if (!visited[i])
flag = false;
if (flag)
{
path.insert(sum);
return;
}
//设置边界
//如果没到递归边界,继续
for (int i = 1; i <= n; i++)
{
if (visited[i] == false)
{
visited[i] = true;
if (sum > *path.begin() && path.size() != 0)
{
visited[i] = false;
continue;
}
temp.push(sum);
sum += cities[start][i];
dfs(i);
sum = temp.top();
temp.pop();
visited[i] = false;
}
}
} int main()
{
scanf("%d", &n);
sum = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &cities[i][j]);
for (int i = 1; i <= n; i++)
dfs(i);
printf("%d\n", *path.begin());
return 0;
}
其他想法

由于此题中旅行商可以从任意城市出发,我在解题的过程中分别搜索了\(n\)个不同起点的解。但可以看出,搜索的不同路径中有大量重和部分,虽然对那些不可能成为最优解的路径进行了剪枝,搜索的效率仍然不高。

于是便有了另外一种思路,即,在图中先搜索出一条最短的哈密顿回路,然后删去这条回路中的最长边,便得到一条哈密顿通路。由最短的哈密顿回路得到的这条哈密顿通路是否是最短的哈密顿回路,我并没有进行严格的证明。

POJ旅行商问题——解题报告的更多相关文章

  1. POJ 1001 解题报告 高精度大整数乘法模版

    题目是POJ1001 Exponentiation  虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...

  2. poj分类解题报告索引

    图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Jou ...

  3. POJ 1003 解题报告

    1.问题描述: http://poj.org/problem?id=1003 2.解题思路: 最直观的的想法是看能不能够直接求出一个通项式,然后直接算就好了, 但是这样好水的样子,而且也不知道这个通项 ...

  4. POJ 1004 解题报告

    1.题目描述: http://poj.org/problem?id=1004 2.解题过程 这个题目咋一看很简单,虽然最终要解出来的确也不难,但是还是稍微有些小把戏在里面,其中最大的把戏就是float ...

  5. POJ 1005 解题报告

    1.题目描述   2.解题思路 好吧,这是个水题,我的目的暂时是把poj第一页刷之,所以水题也写写吧,这个题简单数学常识而已,给定坐标(x,y),易知当圆心为(0,0)时,半圆面积为0.5*PI*(x ...

  6. POJ 3414 解题报告!

    原题: Pots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13227 Accepted: 5550 Special Jud ...

  7. POJ 2411 解题报告

    传送门:http://poj.org/problem?id=2411 题目简述 有一个\(W\)行\(H\)列的广场,需要用\(1*2\)小砖铺满,小砖之间互相不能重叠,问 有多少种不同的铺法? 输入 ...

  8. 广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告

    题目链接:http://poj.org/problem?id=3411 题目意思:N个city 由 m 条路连接,对于一条路(假设连接Cityia和 Cityb),如果从Citya 去 Cityb的途 ...

  9. POJ 2182 解题报告

    Lost Cows Time Limit: 1000 MS Memory Limit: 65536 KB Description N (2 <= N <= 8,000) cows have ...

随机推荐

  1. HTTP&ServletContext&Response对象_文件上传

    今日内容 1. HTTP协议:响应消息 2. Response对象 3. ServletContext对象 HTTP协议 1. 请求消息:客户端发送给服务器端的数据 * 数据格式: 1. 请求行 2. ...

  2. 小白学 Python 数据分析(11):Pandas (十)数据分组

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  3. Java设计模式二

    今天谈的是工厂模式,该模式用于封装和对对象的创建,万物皆对象,那么万物又是产品类,如一个水果厂生产三种水果罐头,我们就可以将这三种水果作为产品类,再定义一个接口用来设定对水果罐头的生成方法,在工厂类中 ...

  4. Cisco模拟器的基本使用

    获取帮助查找命令 只需输入一个'?'便可得到详细的帮助信息,如果想获取c开头的命名,那么直接输入'c?'即可. 在各个模式下切换的方法 给如图所示路由器接口配置IP地址 第一步:安装HWIC-2T(串 ...

  5. layer打开弹窗时传递参数(content:)

    在使用layer打开弹窗时,我希望带一些参数过去,进行某些判断.直接就可以用链接+参数的方式即可. js var userGrade=Mrant layer.open({ title: '权限管理', ...

  6. 学习经典算法—JavaScript篇(一)排序算法

    前端攻城狮--学习常用的排序算法 一.冒泡排序 优点: 所有排序中最简单的,易于理解: 缺点: 时间复杂度O(n^2),平均来说是最差的一种排序方式: 因为在默认情况下,对于已经排好序的部分,此排序任 ...

  7. [LeetCode] 994. Rotting Oranges 腐烂的橘子

    题目: 思路: 每个腐烂的橘子都能将自己上下左右的新鲜橘子传染,像极了现在的肺炎... 如果格子中只有一个腐烂的橘子,那么这便是一个典型的层次遍历,第一个传染多个,称为第二层,第二层传染第三层 但这里 ...

  8. python学习(二)之turtle库绘图

    今天是三月七号,也就是女生节,或者女神节.不知道你是不是有自己喜欢的女孩子,在这里你可以用turtle库绘制一朵玫瑰花,送给你喜欢的姑娘.(拉到最后有惊喜哦)但在画这朵玫瑰花之前,先来一个基础的图形, ...

  9. [2020.03]Unity ML-Agents v0.15.0 环境部署与试运行

    一.ML-Agents简介 近期在学习Unity中的机器学习插件ML-Agents,做一些记录,用以简单记录或交流学习. 先简单说一下机器学习使用的环境场景:高视觉复杂度(Visual Complex ...

  10. Java反射之构造方法反射

    上一篇Java反射之Class类我们介绍了java反射的关键类Class, 反射就是由一个java类映射得到一个java类. 所以,我们自然能想到,一个类中应该有哪些属性,这里做个比方,人有名字年龄等 ...