POJ旅行商问题——解题报告
旅行商问题
总时间限制: 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旅行商问题——解题报告的更多相关文章
- POJ 1001 解题报告 高精度大整数乘法模版
题目是POJ1001 Exponentiation 虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...
- poj分类解题报告索引
图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Jou ...
- POJ 1003 解题报告
1.问题描述: http://poj.org/problem?id=1003 2.解题思路: 最直观的的想法是看能不能够直接求出一个通项式,然后直接算就好了, 但是这样好水的样子,而且也不知道这个通项 ...
- POJ 1004 解题报告
1.题目描述: http://poj.org/problem?id=1004 2.解题过程 这个题目咋一看很简单,虽然最终要解出来的确也不难,但是还是稍微有些小把戏在里面,其中最大的把戏就是float ...
- POJ 1005 解题报告
1.题目描述 2.解题思路 好吧,这是个水题,我的目的暂时是把poj第一页刷之,所以水题也写写吧,这个题简单数学常识而已,给定坐标(x,y),易知当圆心为(0,0)时,半圆面积为0.5*PI*(x ...
- POJ 3414 解题报告!
原题: Pots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13227 Accepted: 5550 Special Jud ...
- POJ 2411 解题报告
传送门:http://poj.org/problem?id=2411 题目简述 有一个\(W\)行\(H\)列的广场,需要用\(1*2\)小砖铺满,小砖之间互相不能重叠,问 有多少种不同的铺法? 输入 ...
- 广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告
题目链接:http://poj.org/problem?id=3411 题目意思:N个city 由 m 条路连接,对于一条路(假设连接Cityia和 Cityb),如果从Citya 去 Cityb的途 ...
- POJ 2182 解题报告
Lost Cows Time Limit: 1000 MS Memory Limit: 65536 KB Description N (2 <= N <= 8,000) cows have ...
随机推荐
- Description Resource Path Location Type cvc-complex-type.2.4.c: The matching 解决问题
2017-03-02 10:08:03,112 [localhost-startStop-1] ERROR org.springframework.web.servlet.DispatcherServ ...
- Flutter 拖拽排序组件 ReorderableListView
注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 ReorderableListView是通过长按拖动某一项 ...
- Python——五分钟带你弄懂迭代器与生成器,夯实代码能力
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是周一Python专题,给大家带来的是Python当中生成器和迭代器的使用. 我当初第一次学到迭代器和生成器的时候,并没有太在意,只是觉 ...
- 必备技能五、router路由钩子
在路由跳转的时候,我们需要一些权限判断或者其他操作.这个时候就需要使用路由的钩子函数. 定义:路由钩子主要是给使用者在路由发生变化时进行一些特殊的处理而定义的函数. 总体来讲vue里面提供了三大类钩子 ...
- scrapy 在爬取过程中抓取下载图片
先说前提,我不推荐在sarapy爬取过程中使用scrapy自带的 ImagesPipeline 进行下载,是在是太耗时间了 最好是保存,在使用其他方法下载 我这个是在 https://blog.csd ...
- 项目测试中发现产品bug怎么办
我所在的产品线,并非公司最大最强的产品 甚至为了推广我们这个产品,一般会拿给客户先免费试用 而在试用之前,是要经过一番通测的,测得很急,测得很快 所以产品bug非常多 那么在测试项目的时候,自然会发现 ...
- python第一次作业
import turtle turtle.pensize(2) turtle.pencolor("black") turtle.fillcolor("red") ...
- 双列集合Map相关面试题
一.了解Map集合吗?Map集合都有哪些实现 HashMap HashTable LinkedHashMap TreeMap ConcurrentHashMap 二.HashMap和HashTable ...
- layui的form表单的checkbox全选与全不选问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <m ...
- VsCode从零开始配置一个属于自己的Vue开发环境
vscode vue VsCode算是比较热门的一个代码编辑器了,全名Visual Studio Code下载地址:点我去下载插件众多,功能齐全,我在平常开发过程中都是用的它,整理了些自认好用的插件, ...