#220-[TSP,DFS,Floyd]送披萨

Description

披萨店为其能尽可能快地将披萨送到顾客手中感到骄傲。不幸的是,由于削减开支,现在他们只能雇佣一个司机来送披萨。这个司机在送披萨之前,要等1个或多个(最多10个)要处理的订单。司机希望送货和返回披萨店能走最短的路线,即使路上会走过同一地点或经过披萨店多次。现在请你编写一个程序来帮助这个司机。

Input

输入由多个测试用例组成。第一行给出一个整数n,表示要送货的订单数,1<=n<=10。然后有n+1行,每行给出n+1个整数,表示披萨店(编号为0)和n个地点(编号从1到n)之间到达所用的时间。在第i行的第j个值表示从地点i直接到地点j,在路上不去其他地点的时间。注意,由于不同的速度限制和红绿灯,从i到j通过其他地点可能会比直接走更快;而且,时间值可能不对称,也就是说,直接从地点i到j所用的时间可能和从地点j到地点i所用的时间不一样。输入以n=0终止。

Output

对每个测试用例,输出一个数,表示送完所有的披萨并返回披萨店所用的最少时间。

3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
0
  • Sample Input

8
  • Sample Output

Source/Category

练习题-状压dp 

先Floyd,然后暴力DFS

典型TSP问题

#include 
#include 

using namespace std;
const int MAXN = 13;

int dis[MAXN][MAXN], n, res; bool vis[MAXN];

void dfs(int u, int k, int d) { // 暴力
	if (k==n) { // 全部到了
		res=min(res,d+dis[u][0]); return; // 还要加上回去的
	}
	for (int i=1; i<=n; ++i) { // 枚举
		if (!vis[i]) {
			vis[i]=true; dfs(i,k+1,d+dis[u][i]); vis[i]=false;
		}
	}
}
int main() {
	scanf("%d", &n); if (!n) return 0;
	for (int i=0; i<=n; ++i) {
		for (int j=0; j<=n; ++j) scanf("%d", &dis[i][j]); // 输入距离
	}
	for (int k=0; k<=n; ++k) { // 跑Floyd
		for (int i=0; i<=n; ++i) {
			for (int j=0; j<=n; ++j) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
		}
	}
	res=2e+09; dfs(0, 0, 0); printf("%d\n", res);
	main(); return 0;
}

 

你可能感兴趣的:(刷题)