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 ...
随机推荐
- SQL Server 最小日志记录
SQL Server之所以记录事务日志,首要目的是为了把失败或取消的操作还原到最原始的状态,但是,并不是所有的操作都需要完全记录事务日志,比如,在一个空表上放置排他锁,把大量的数据插入到该空表中.即使 ...
- 基于JS正则实现模板数据动态渲染
最近业务上需要动态渲染模板数据: 一.业务需求: 1.前端后端定义好模板以及变量名,根据打印机类型转换成对应sdk需要的标签模板,保存数据库 2.订单数据是前端根据支付结果获取的,最终渲染完的数据模板 ...
- svg和css3创建环形渐变进度条
在负责的项目中,有一个环形渐变读取进度的效果的需求,于是在网上查阅相关资料整理一下.代码如下: <!DOCTYPE html> <html lang="en"&g ...
- 机器学习 - LSTM应用之sequence generation
概述 LSTM在机器学习上面的应用是非常广泛的,从股票分析,机器翻译 到 语义分析等等各个方面都有它的用武之地,经过前面的对于LSTM结构的分析,这一节主要介绍一些LSTM的一个小应用,那就是sequ ...
- .net core WebAPI+EF 动态接收前台json,并动态修改数据库
用API开发的人都知道,常用的后台接收参数就是建个DTO,然后前台把这个DTO传过来.后台再更新,例如如下例子: public async Task<IActionResult> PutM ...
- 仿IntelliJ Darcula的Swing主题FlatLaf使用方法
最近Sandeepin想写个基于Java Swing的RSS阅读器练练手,不过Swing默认主题太丑了,切成系统原生的主题也不是非常好看,正好感觉开发时用的IDEA主题很不错,不管是Light还是Da ...
- django 从零开始 10 缓存控制
设置django缓存,比如一些访问频繁的页面 首页 并且不需要进行太大的变化,那么可以设置为一定是时间内请求该url视图 不经过视图计算直接返回缓存的内容 django文档选择了几种方式,但是我这 ...
- python第一次作业
import turtle turtle.pensize(2) turtle.pencolor("black") turtle.fillcolor("red") ...
- gitbook 入门教程之超高颜值的思维导图simple-mind-map插件
欢迎访问 gitbook-plugin-simple-mind-map 官网
- video 在iphone手机的ios系统和微信端无法自动播放
描述:video 在iphone手机,微信端无法自动播放,ios系统下不能自动播放视频.而且如果没有autoplay属性,在微信端点击一次,弹不出视频,要一直触着两秒后才可以打开视频.如果点击播放的话 ...