TSP问题
2015-12-26 19:14
225 查看
问题 K: 送外卖
题目描述
在美团和饿了么大行其道的今天,囊中羞涩的小周和小美,也随大流加入了配送员的行列。每天下课后,他们都去堕落街帮北京烤鸭店送外卖。过了好些日子,小周发现每次送外卖,小美总比自己先回来,就算自己拼命跑啊跑,也总是比她慢,明明小美也是和自己一样,走着去送外卖的(等外卖的都饿死了╮(╯﹏╰)╭)。
小周忍不住问了小美这是怎么回事,小美说:“笨蛋,本小姐每次出去都选最短的路,肯定比你走远的路快啊!”
小周恍然大悟,深恨自己怎么没有早早想到这一点,不过亡羊补牢,为时未晚,立即决定效仿小美的做法。小周将店的位置标号为0,其他要送外卖的位置标号分别是1,2,3……然后又将各个标号之间的距离做了一张二维表A,其中A[0][i]代表从店家出发到第i个外卖点的距离,A[i][j](i!=0&&j!=0)表示第i个外卖点到第j个外卖点的距离。
小周每次都从店里出发,送完所有外卖之后,就从最后一个送完外卖的地点径直地回到店里,因为直接回去总是最近的,小周统计出来的表的确也是这样的。保证矩阵对称且主对角线上的元素都是0。
不过由于小周实在是太忙了,连计算最短路线的时间都没有,现在给你这张小周做好的表,请你帮小周确定一下最短的路线吧!
输入
第一行输入数据的组数T(1<=T<=50)。对于每一组数据,第一行一个n(0 < n <= 9),代表要送的外卖数量,然后一个(n+1)*(n+1)的矩阵A,代表小周的统计出来距离表,0 <= A[i][j] <= 500。
输出
对于每组数据,输出送完所有外卖并回到店里的最短的距离样例输入
21
0 52
52 0
2
0 319
430 319
0 96
430 96
0
样例输出
104845
题目地址:http://125.221.232.253/JudgeOnline/problem.php?cid=1168&pid=10
TSP问题:
递归思想:
从店家开始,尝试每种可能的送法,(试完后恢复局面)
送完后把局面交给下一状态
a[i][j]表示从i送到j
public class Problem_cid_1168_pid_10 { static int min=5000; public static void main(String[] args) { Scanner cin = new Scanner(System.in); int t = cin.nextInt(); while (t-->0) { int num=cin.nextInt(); int a[][]=new int[num+1][num+1];//距离 for (int i = 0; i < a.length; i++) { for (int j = 0; j < a.length; j++) { a[i][j]=cin.nextInt(); } } int currentsum=0; boolean[][] b=new boolean[num+1][num+1]; for (int i = 0; i < b.length; i++)b[i][i]=true; min=5000; boolean []hasdeal=new boolean[num+1]; f(num,a,currentsum,1, currentsum,b,0,hasdeal); System.out.println(min); } } /** *@param num:外卖份数 *@param a:距离矩阵 *@param currentsum:当前计算的距离总合 *@param y:下一份外卖在哪 *@param dealnum:当前送出的外卖数 *@param b:标记外卖是否已经送出 *@param x:上一份外卖在哪 */ private static void f(int num,int[][] a, int currentsum,int y,int dealnum,boolean [][]b,int x,boolean [] hasdeal) { if (dealnum==num) { int ans=currentsum+a[y][0]; // System.out.println("dealnum="+dealnum+" currentsum="+currentsum+" a["+x+"][0]="+a[x][0]+" ans="+ans); min=Math.min(ans, min); return ; } if (currentsum>min) return ; for (int i = 1; i <a[0].length ; i++) {//从这份外卖开始,尝试送出 if (i!=x&&b[x][i]==false&&hasdeal[i]==false) { b[i][x]=b[x][i]=true; hasdeal[i]=true; f(num,a, currentsum+a[x][i],i, dealnum+1, b, i,hasdeal); hasdeal[i]=false; b[i][x]=b[x][i]=false; } } } }
相关文章推荐
- 5-30 字符串的冒泡排序 (20分)
- OC中集合的基本使用
- UML图箭头关系
- Android自定义控件之仿知乎详情页
- 前端模块化实践----使用webpack打包js代码
- InvoiceCancelSendApAction
- N_F1_APPROVE
- Spring加载resource时classpath*:与classpath:的区别
- POJ2251——BFS三维迷宫
- paip. 混合编程的实现resin4 (自带Quercus ) 配置 php 环境
- 23种设计模式UML图
- 自定义EditText样式-(包括光标背景)
- ruby on rails模拟HTTP请求发生错误:end of file reached
- 高中数学必修1 之 指数函数、对数函数和幂函数
- Sql2008 r2 使用ftp 公布和订阅方式同步数据
- 初学linux的rpm和前端管理工具yum
- spring注入properties属性配置
- 数值类型 访问权限控制以及部分运算符
- 进制转换
- C代码中如何调用C++ C++中如何调用C