您的位置:首页 > 其它

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。

输出

对于每组数据,输出送完所有外卖并回到店里的最短的距离

样例输入

2
1
0 52
52 0
2
0 319
430 319
0 96
430 96
0

样例输出

104
845
题目地址: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;
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: