题目链接
金典TSP+压缩状态DP
TSP解法介绍:浅谈旅行商问题(动态规划,回溯实现)
压缩状态DP解法请参考:旅行商问题解法
思路
上面的压缩状态DP算法经典,但是dp状态转移方程的构造理解起来微难,可以使用贪心+dfs的思路来找到花费最小的环。
即当前旅行到i点,要使得全局花费最小,则需要寻找与i最近且没有被旅行过的点去旅行(贪心)。但是可能会出现多个未旅行过的点,他们与当前i点距离相等且都是最小,需要来对这些点进行逐一搜索(dfs),全部点都遍历完成,则更新全局最小花费。(也可以理解为剪枝的dfs)
要达到全局最优还需要对出发点进行轮询指定,并不断更新全局最小花费,最终获得最优解。
代码
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
public static int[] mark = new int[21];
public static int[][] graph = new int[21][21];
public static int minCostSum = 0x7fffffff;
public static int n;
public static LinkedList<Elem> stack = new LinkedList<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
//接收数据
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) {
graph[i][j] = in.nextInt();
}
mark[i] = 0;
}
//针对每一个点作为起点都搜索一次(非常重要)
for(int i=1;i<=n;i++){
mark[i] = 1;
Elem elem = new Elem(i);
stack.addLast(elem);
dfs();
}
System.out.println(minCostSum);
}
public static void dfs(){
//找到一个环则更新最下环花费
if(stack.size()==n){
int startSite = stack.getFirst().site;
int endSite = stack.getLast().site;
//找到最短路径后,首尾相接构成一个环(要回到起始地)
int cost = graph[startSite][endSite]+stack.getLast().costSum;
minCostSum = Math.min(minCostSum,cost);
}
//取出前一个环
Elem elem = stack.getLast();
int nowSite = elem.site;
int nowCostSum = elem.costSum;
int minCost = 0x7fffffff;
//找到没有旅游过的景点的最少路费
for(int i=1;i<=n;i++)
if(mark[i]!=1 && graph[nowSite][i] < minCost)
minCost = graph[nowSite][i];
//对没有旅游过且满足路费等于最小路费的景点做一次搜索
for(int i=1;i<=n;i++){
if(mark[i]!=1 && graph[nowSite][i] == minCost){
Elem elem_ = new Elem(i);
elem_.costSum = nowCostSum + minCost;
stack.addLast(elem_);
mark[i] = 1;
dfs();
}
}
stack.removeLast();
mark[nowSite] = 0;
}
}
class Elem{
public int site; //当前处理的Site
public int costSum = 0; //处理到当前Site的花费总和
public Elem(int site){
this.site = site;
}
}
问题
有一组数据没过,欢迎大佬指导
输入:
18
0 8 5 9 4 3 4 5 7 9 6 5 5 8 4 5 7 5
8 0 7 4 3 3 5 4 5 7 5 4 6 6 4 5 6 5
5 7 0 4 3 2 8 6 2 5 6 3 7 4 3 3 7 6
9 4 4 0 1 3 5 9 5 3 7 3 8 9 3 4 6 6
4 3 3 1 0 7 6 8 7 5 5 4 8 6 5 6 5 4
3 3 2 3 7 0 5 4 7 9 6 5 7 3 5 8 4 4
4 5 8 5 6 5 0 7 5 6 8 6 6 2 6 9 5 4
5 4 6 9 8 4 7 0 7 4 9 7 5 4 6 9 4 3
7 5 2 5 7 7 5 7 0 6 5 8 5 6 3 4 9 3
9 7 5 3 5 9 6 4 6 0 6 9 6 7 3 4 8 3
6 5 6 7 5 6 8 9 5 6 0 6 5 7 8 6 9 2
5 4 3 3 4 5 6 7 8 9 6 0 8 5 8 6 8 1
5 6 7 8 8 7 6 5 5 6 5 8 0 3 9 3 7 1
8 6 4 9 6 3 2 4 6 7 7 5 3 0 9 4 5 2
4 4 3 3 5 5 6 6 3 3 8 8 9 9 0 8 7 9
5 5 3 4 6 8 9 9 4 4 6 6 3 4 8 0 7 10
7 6 7 6 5 4 5 4 9 8 9 8 7 5 7 7 0 11
5 5 6 6 4 4 4 3 3 3 2 1 1 2 9 10 11 0
预期输出:
54
实际输出:
55
浙公网安备 33010602011771号